machinalayout 0.1.0 → 0.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 +295 -49
- package/dist/chunk-2ZQ2RFFI.js +400 -0
- package/dist/chunk-33CKBEJH.js +186 -0
- package/dist/chunk-BJOQRPPX.js +382 -0
- package/dist/chunk-KYWOCAHK.js +205 -0
- package/dist/chunk-RJYRJ3LD.js +0 -0
- package/dist/chunk-SVWYWI7I.js +59 -0
- package/dist/chunk-VREK57S3.js +13 -0
- package/dist/chunk-ZVDE7PX4.js +222 -0
- package/dist/debugOverlay-pJpj0n5H.d.ts +125 -0
- package/dist/deus/index.d.ts +14 -0
- package/dist/deus/index.js +26 -0
- package/dist/dispatch/index.d.ts +49 -0
- package/dist/dispatch/index.js +217 -0
- package/dist/handoff/index.d.ts +44 -0
- package/dist/handoff/index.js +83 -0
- package/dist/index.d.ts +54 -236
- package/dist/index.js +753 -583
- package/dist/inspect/index.d.ts +8 -0
- package/dist/inspect/index.js +97 -0
- package/dist/react/index.d.ts +41 -0
- package/dist/react/index.js +9 -0
- package/dist/react-native/index.d.ts +30 -0
- package/dist/react-native/index.js +84 -0
- package/dist/screenCatalog-ZjonGiOi.d.ts +46 -0
- package/dist/text/index.d.ts +10 -0
- package/dist/text/index.js +9 -0
- package/dist/text/react/index.d.ts +14 -0
- package/dist/text/react/index.js +7 -0
- package/dist/text/react-native/index.d.ts +16 -0
- package/dist/text/react-native/index.js +155 -0
- package/dist/text/vue/index.d.ts +113 -0
- package/dist/text/vue/index.js +202 -0
- package/dist/types-B90jb3RW.d.ts +184 -0
- package/dist/types-C4poVJpR.d.ts +74 -0
- package/dist/types-DLYAhNXw.d.ts +32 -0
- package/dist/vue/index.d.ts +173 -0
- package/dist/vue/index.js +112 -0
- package/docs/adapter-packaging-a0-plan.md +352 -0
- package/docs/adapters.md +19 -0
- package/docs/api-coherence-m8-audit.md +397 -0
- package/docs/deusmachina.md +108 -0
- package/docs/error-codes.md +95 -0
- package/docs/grid-arrange-m5a-contract.md +480 -0
- package/docs/grid-arrange.md +51 -0
- package/docs/inspection-and-handoff.md +126 -0
- package/docs/layout-interpolation.md +52 -0
- package/docs/machina-dispatch-d0-contract.md +496 -0
- package/docs/machina-dispatch.md +143 -0
- package/docs/named-layers.md +40 -0
- package/docs/react-adapter.md +63 -58
- package/docs/react-native-adapter.md +56 -0
- package/docs/react-native-text-renderer.md +50 -0
- package/docs/reference-alignment-m7a-contract.md +384 -0
- package/docs/reference-alignment.md +44 -0
- package/docs/responsive-variants.md +54 -0
- package/docs/screen-catalog-and-viewports.md +124 -0
- package/docs/stack-geometry-helpers.md +115 -0
- package/docs/vue-adapter.md +55 -0
- package/docs/vue-text-renderer.md +55 -0
- package/package.json +127 -60
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
toResolvedTree
|
|
3
|
+
} from "../chunk-SVWYWI7I.js";
|
|
4
|
+
import "../chunk-VREK57S3.js";
|
|
5
|
+
|
|
6
|
+
// src/vue/MachinaVueView.ts
|
|
7
|
+
import { computed, defineComponent, h } from "vue";
|
|
8
|
+
var normalizeLayerZ = (v) => v === void 0 || !Number.isFinite(v) || !Number.isInteger(v) || v < -5 || v > 5 ? 0 : v;
|
|
9
|
+
var getEffectiveLayer = (n, d) => n.layer ?? d;
|
|
10
|
+
var getEffectiveLayerZ = (n, l, d) => normalizeLayerZ(l[getEffectiveLayer(n, d)]?.z);
|
|
11
|
+
var MachinaVueView = defineComponent({
|
|
12
|
+
name: "MachinaVueView",
|
|
13
|
+
props: {
|
|
14
|
+
layout: { type: Object, required: true },
|
|
15
|
+
views: { type: Object, default: () => ({}) },
|
|
16
|
+
viewData: { type: Object, default: () => ({}) },
|
|
17
|
+
nodeData: { type: Object, default: () => ({}) },
|
|
18
|
+
layers: {
|
|
19
|
+
type: Object,
|
|
20
|
+
default: () => ({ base: { z: 0 } })
|
|
21
|
+
},
|
|
22
|
+
defaultLayer: { type: String, default: "base" },
|
|
23
|
+
debug: { type: Boolean, default: false },
|
|
24
|
+
rootClass: { type: null, default: void 0 },
|
|
25
|
+
rootStyle: { type: null, default: void 0 },
|
|
26
|
+
nodeClass: { type: null, default: void 0 },
|
|
27
|
+
nodeStyle: { type: null, default: void 0 },
|
|
28
|
+
nodeContainment: {
|
|
29
|
+
type: String,
|
|
30
|
+
default: "layout-paint"
|
|
31
|
+
},
|
|
32
|
+
nodeContentVisibility: { type: String, default: "none" },
|
|
33
|
+
nodeContainIntrinsicSize: { type: String, default: void 0 }
|
|
34
|
+
},
|
|
35
|
+
setup(props) {
|
|
36
|
+
const tree = computed(() => toResolvedTree(props.layout));
|
|
37
|
+
const renderNode = (node, parentRect) => {
|
|
38
|
+
const viewKey = node.view ?? node.slot;
|
|
39
|
+
const View = viewKey ? props.views[viewKey] : void 0;
|
|
40
|
+
const left = node.rect.x - parentRect.x;
|
|
41
|
+
const top = node.rect.y - parentRect.y;
|
|
42
|
+
const layer = getEffectiveLayer(node, props.defaultLayer);
|
|
43
|
+
const layerZ = getEffectiveLayerZ(node, props.layers, props.defaultLayer);
|
|
44
|
+
const baseStyle = {
|
|
45
|
+
position: "absolute",
|
|
46
|
+
left: `${left}px`,
|
|
47
|
+
top: `${top}px`,
|
|
48
|
+
width: `${node.rect.width}px`,
|
|
49
|
+
height: `${node.rect.height}px`,
|
|
50
|
+
boxSizing: "border-box",
|
|
51
|
+
zIndex: `${layerZ * 100 + (node.z ?? 0)}`,
|
|
52
|
+
...props.nodeContainment === "layout-paint" ? { contain: "layout paint" } : null,
|
|
53
|
+
...props.nodeContainment === "strict" ? { contain: "strict" } : null,
|
|
54
|
+
...props.nodeContentVisibility === "auto" ? { contentVisibility: "auto" } : null,
|
|
55
|
+
...props.nodeContainIntrinsicSize !== void 0 ? { containIntrinsicSize: props.nodeContainIntrinsicSize } : null,
|
|
56
|
+
...props.debug ? { outline: "1px dashed rgba(59, 130, 246, 0.9)" } : null
|
|
57
|
+
};
|
|
58
|
+
const rendered = View && props.layout.nodes[node.id] ? h(View, {
|
|
59
|
+
id: node.id,
|
|
60
|
+
rect: { ...node.rect },
|
|
61
|
+
debugLabel: node.debugLabel,
|
|
62
|
+
node: {
|
|
63
|
+
...props.layout.nodes[node.id],
|
|
64
|
+
rect: { ...props.layout.nodes[node.id].rect }
|
|
65
|
+
},
|
|
66
|
+
viewKey,
|
|
67
|
+
viewData: viewKey ? props.viewData[viewKey] : void 0,
|
|
68
|
+
nodeData: props.nodeData[node.id]
|
|
69
|
+
}) : null;
|
|
70
|
+
const kids = [...node.children].map((child, index) => ({ child, index })).sort(
|
|
71
|
+
(a, b) => getEffectiveLayerZ(a.child, props.layers, props.defaultLayer) - getEffectiveLayerZ(b.child, props.layers, props.defaultLayer) || (a.child.z ?? 0) - (b.child.z ?? 0) || a.index - b.index
|
|
72
|
+
).map(({ child }) => renderNode(child, node.rect));
|
|
73
|
+
return h(
|
|
74
|
+
"div",
|
|
75
|
+
{
|
|
76
|
+
key: node.id,
|
|
77
|
+
class: props.nodeClass,
|
|
78
|
+
style: [baseStyle, props.nodeStyle],
|
|
79
|
+
"data-machina-node-id": node.id,
|
|
80
|
+
"data-machina-slot": node.slot,
|
|
81
|
+
"data-machina-view": viewKey,
|
|
82
|
+
"data-machina-debug-label": node.debugLabel,
|
|
83
|
+
"data-machina-layer": layer
|
|
84
|
+
},
|
|
85
|
+
[props.debug ? h("small", {}, node.debugLabel ?? node.id) : null, rendered, ...kids]
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
return () => {
|
|
89
|
+
const root = tree.value;
|
|
90
|
+
return h(
|
|
91
|
+
"div",
|
|
92
|
+
{
|
|
93
|
+
class: props.rootClass,
|
|
94
|
+
style: [
|
|
95
|
+
{
|
|
96
|
+
position: "relative",
|
|
97
|
+
width: `${root.rect.width}px`,
|
|
98
|
+
height: `${root.rect.height}px`,
|
|
99
|
+
boxSizing: "border-box"
|
|
100
|
+
},
|
|
101
|
+
props.rootStyle
|
|
102
|
+
],
|
|
103
|
+
"data-machina-root-id": root.id
|
|
104
|
+
},
|
|
105
|
+
[renderNode(root, root.rect)]
|
|
106
|
+
);
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
export {
|
|
111
|
+
MachinaVueView
|
|
112
|
+
};
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
# Adapter Packaging A0 Plan
|
|
2
|
+
|
|
3
|
+
## 1) Executive summary
|
|
4
|
+
|
|
5
|
+
MachinaLayout should stay as a **single npm package during `0.x`**, but move toward a **subpath-exported adapter model** so new adapters do not impose framework installs on every user.
|
|
6
|
+
|
|
7
|
+
Recommended direction:
|
|
8
|
+
|
|
9
|
+
- Keep `machinalayout` root import stable for compatibility during `0.x`.
|
|
10
|
+
- Add framework-specific adapter entrypoints as subpaths (`machinalayout/react`, `machinalayout/text/react`, future `machinalayout/react-native`, `machinalayout/vue`, etc.).
|
|
11
|
+
- Treat new framework peers (`react-native`, `vue`) as **optional peers** when their adapters are added.
|
|
12
|
+
- Keep runtime/package behavior unchanged in A0; implement packaging/build updates as A1 prerequisites.
|
|
13
|
+
|
|
14
|
+
## 2) Current package/export state (observed)
|
|
15
|
+
|
|
16
|
+
### Package/build
|
|
17
|
+
|
|
18
|
+
- Package name is `machinalayout`, version `0.1.0`, ESM package type.
|
|
19
|
+
- Build command uses `tsup` with a **single entry**: `src/index.ts`.
|
|
20
|
+
- Current output is a **single dist entrypoint**:
|
|
21
|
+
- `dist/index.js`
|
|
22
|
+
- `dist/index.d.ts`
|
|
23
|
+
- `exports` currently expose only `"."`.
|
|
24
|
+
|
|
25
|
+
### Peer dependencies
|
|
26
|
+
|
|
27
|
+
- Current peers are:
|
|
28
|
+
- `react` (`>=18 <20`)
|
|
29
|
+
- `react-dom` (`>=18 <20`)
|
|
30
|
+
- No optional peer metadata yet.
|
|
31
|
+
|
|
32
|
+
### Public exports and source layout
|
|
33
|
+
|
|
34
|
+
- `src/index.ts` re-exports core, React adapter (`./react`), and text module (`./text`).
|
|
35
|
+
- React adapter exists under `src/react`.
|
|
36
|
+
- Text parser/types and React text renderer exist under `src/text` and `src/text/react`.
|
|
37
|
+
- README examples/documentation currently import React adapter from root (`machinalayout`).
|
|
38
|
+
|
|
39
|
+
### Packaging snapshot
|
|
40
|
+
|
|
41
|
+
- `npm pack --dry-run` currently includes `dist` (single bundle), README, LICENSE, and docs.
|
|
42
|
+
- No subpath build artifacts are currently emitted.
|
|
43
|
+
|
|
44
|
+
## 3) Recommended package strategy
|
|
45
|
+
|
|
46
|
+
### Evaluated options
|
|
47
|
+
|
|
48
|
+
#### A. Single package + subpath exports (recommended for now)
|
|
49
|
+
|
|
50
|
+
Pros:
|
|
51
|
+
|
|
52
|
+
- Minimal project/process overhead while API is still evolving.
|
|
53
|
+
- Keeps install/discovery simple for early adopters.
|
|
54
|
+
- Preserves existing import compatibility.
|
|
55
|
+
|
|
56
|
+
Cons:
|
|
57
|
+
|
|
58
|
+
- `exports`/build matrix becomes more complex.
|
|
59
|
+
- Peer policy must clearly separate required vs optional framework peers.
|
|
60
|
+
|
|
61
|
+
#### B. Separate packages (`@machina/*`) later
|
|
62
|
+
|
|
63
|
+
Pros:
|
|
64
|
+
|
|
65
|
+
- Clean dependency isolation per framework.
|
|
66
|
+
- Natural long-term scaling for adapters.
|
|
67
|
+
|
|
68
|
+
Cons:
|
|
69
|
+
|
|
70
|
+
- Multi-package release/publishing overhead now.
|
|
71
|
+
- More migration friction before APIs settle.
|
|
72
|
+
|
|
73
|
+
### Decision
|
|
74
|
+
|
|
75
|
+
For `0.x`, use **single package + subpath exports**. Reassess split packages after adapter APIs stabilize and usage justifies monorepo/package split effort.
|
|
76
|
+
|
|
77
|
+
## 4) Proposed subpath export map
|
|
78
|
+
|
|
79
|
+
Target import shapes:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { resolveLayoutRows } from "machinalayout";
|
|
83
|
+
import { MachinaReactView } from "machinalayout/react";
|
|
84
|
+
import { parseMachinaText } from "machinalayout/text";
|
|
85
|
+
import { MachinaTextView } from "machinalayout/text/react";
|
|
86
|
+
import { MachinaReactNativeView } from "machinalayout/react-native";
|
|
87
|
+
import { MachinaVueView } from "machinalayout/vue";
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Export policy:
|
|
91
|
+
|
|
92
|
+
- **Keep root exports unchanged during `0.x`** for compatibility.
|
|
93
|
+
- Introduce and document subpath exports as preferred for adapters.
|
|
94
|
+
- New adapters (`react-native`, `vue`, future) should be **subpath-only**.
|
|
95
|
+
- Existing root React exports remain temporarily for non-breaking transition.
|
|
96
|
+
|
|
97
|
+
## 5) Peer dependency policy
|
|
98
|
+
|
|
99
|
+
### Near term (`0.x`, current compatibility)
|
|
100
|
+
|
|
101
|
+
- Keep `react` and `react-dom` as non-optional peers while root still exports React adapter surfaces.
|
|
102
|
+
- When adding adapter subpaths:
|
|
103
|
+
- Add `react-native` peer + `peerDependenciesMeta.react-native.optional = true`.
|
|
104
|
+
- Add `vue` peer + `peerDependenciesMeta.vue.optional = true`.
|
|
105
|
+
|
|
106
|
+
### Later (future major or de-rooting)
|
|
107
|
+
|
|
108
|
+
- If React DOM adapter is no longer root-exported, convert renderer peers to optional and strictly subpath-scoped usage.
|
|
109
|
+
|
|
110
|
+
Rationale: users should only need the framework peer for the adapter they import.
|
|
111
|
+
|
|
112
|
+
## 6) Build output proposal
|
|
113
|
+
|
|
114
|
+
A1 prerequisite: move from single-entry build to multi-entry/subpath build.
|
|
115
|
+
|
|
116
|
+
Proposed dist shape:
|
|
117
|
+
|
|
118
|
+
```txt
|
|
119
|
+
dist/index.js
|
|
120
|
+
dist/index.d.ts
|
|
121
|
+
dist/react/index.js
|
|
122
|
+
dist/react/index.d.ts
|
|
123
|
+
dist/text/index.js
|
|
124
|
+
dist/text/index.d.ts
|
|
125
|
+
dist/text/react/index.js
|
|
126
|
+
dist/text/react/index.d.ts
|
|
127
|
+
dist/react-native/index.js
|
|
128
|
+
dist/react-native/index.d.ts
|
|
129
|
+
dist/vue/index.js
|
|
130
|
+
dist/vue/index.d.ts
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Build notes:
|
|
134
|
+
|
|
135
|
+
- Use tsup multi-entry configuration (or equivalent) with explicit entry files.
|
|
136
|
+
- Externalize framework runtimes in adapter bundles:
|
|
137
|
+
- `react`, `react-dom`, `react/jsx-runtime`
|
|
138
|
+
- `react-native`
|
|
139
|
+
- `vue`
|
|
140
|
+
- Keep core runtime free of adapter-specific runtime imports.
|
|
141
|
+
|
|
142
|
+
## 7) Source tree proposal
|
|
143
|
+
|
|
144
|
+
Recommended organization:
|
|
145
|
+
|
|
146
|
+
```txt
|
|
147
|
+
src/
|
|
148
|
+
index.ts
|
|
149
|
+
react/
|
|
150
|
+
index.ts
|
|
151
|
+
MachinaReactView.tsx
|
|
152
|
+
react-native/
|
|
153
|
+
index.ts
|
|
154
|
+
MachinaReactNativeView.tsx
|
|
155
|
+
vue/
|
|
156
|
+
index.ts
|
|
157
|
+
MachinaVueView.ts
|
|
158
|
+
text/
|
|
159
|
+
index.ts
|
|
160
|
+
types.ts
|
|
161
|
+
parseMachinaText.ts
|
|
162
|
+
react/
|
|
163
|
+
index.ts
|
|
164
|
+
MachinaTextView.tsx
|
|
165
|
+
react-native/
|
|
166
|
+
index.ts
|
|
167
|
+
MachinaNativeTextView.tsx
|
|
168
|
+
vue/
|
|
169
|
+
index.ts
|
|
170
|
+
MachinaVueTextView.ts
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Guideline:
|
|
174
|
+
|
|
175
|
+
- Layout adapters: `src/<adapter>`.
|
|
176
|
+
- Text renderers: `src/text/<adapter>`.
|
|
177
|
+
|
|
178
|
+
This keeps parser/core text independent from renderer frameworks.
|
|
179
|
+
|
|
180
|
+
## 8) Adapter API previews (non-binding)
|
|
181
|
+
|
|
182
|
+
### React Native layout adapter
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
export type { MachinaReactNativeViewProps, MachinaNativeSlotProps };
|
|
186
|
+
export { MachinaReactNativeView };
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Expected behavior:
|
|
190
|
+
|
|
191
|
+
- Uses RN `View` + style objects.
|
|
192
|
+
- No `className`, no DOM data-attributes.
|
|
193
|
+
- No DOM containment/content-visibility policy.
|
|
194
|
+
- Preserve layout semantics, `viewData`/`nodeData`, layers/z ordering, and parent-local coordinates.
|
|
195
|
+
|
|
196
|
+
### Vue layout adapter
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
export type { MachinaVueViewProps, MachinaVueSlotProps };
|
|
200
|
+
export { MachinaVueView };
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Expected behavior:
|
|
204
|
+
|
|
205
|
+
- Vue component/composable renderer using `h()`.
|
|
206
|
+
- Supports `layout`, `views`, `viewData`, `nodeData`, `layers`, `defaultLayer`, `debug`.
|
|
207
|
+
- Dynamic view mapping via component references.
|
|
208
|
+
|
|
209
|
+
### Text
|
|
210
|
+
|
|
211
|
+
- `parseMachinaText` remains framework-agnostic in `machinalayout/text`.
|
|
212
|
+
- Framework renderers exposed by subpath (`text/react`, future `text/react-native`, `text/vue`).
|
|
213
|
+
|
|
214
|
+
## 9) Test strategy
|
|
215
|
+
|
|
216
|
+
Principles:
|
|
217
|
+
|
|
218
|
+
- Core tests always run and remain framework-independent.
|
|
219
|
+
- Adapter tests are isolated by adapter folders and entrypoints.
|
|
220
|
+
- Avoid forcing heavy framework stacks for users who do not use them.
|
|
221
|
+
|
|
222
|
+
Proposed test layout:
|
|
223
|
+
|
|
224
|
+
```txt
|
|
225
|
+
test/
|
|
226
|
+
core/...
|
|
227
|
+
react/...
|
|
228
|
+
react-native/...
|
|
229
|
+
vue/...
|
|
230
|
+
text/
|
|
231
|
+
core/...
|
|
232
|
+
react/...
|
|
233
|
+
react-native/...
|
|
234
|
+
vue/...
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Execution approach (A1+):
|
|
238
|
+
|
|
239
|
+
- Default CI lane: core + existing React lanes.
|
|
240
|
+
- Adapter lanes:
|
|
241
|
+
- RN adapter tests in dedicated job/environment.
|
|
242
|
+
- Vue adapter tests in dedicated job/environment.
|
|
243
|
+
- Early RN adapter tests can start with type-level/shape tests and minimal render checks before deeper platform-specific behavior.
|
|
244
|
+
|
|
245
|
+
## 10) Documentation plan
|
|
246
|
+
|
|
247
|
+
Planned docs additions:
|
|
248
|
+
|
|
249
|
+
- `docs/react-native-adapter.md`
|
|
250
|
+
- `docs/vue-adapter.md`
|
|
251
|
+
- `docs/adapter-packaging-a0-plan.md` (this file)
|
|
252
|
+
- README update to clarify preferred import paths and adapter dependency expectations.
|
|
253
|
+
|
|
254
|
+
Docs guidance:
|
|
255
|
+
|
|
256
|
+
- Show subpath imports for framework adapters.
|
|
257
|
+
- Keep compatibility notes for root React imports during `0.x`.
|
|
258
|
+
- Explicitly state optional peer policy for non-default adapters.
|
|
259
|
+
- Keep adapter docs aligned to one conceptual model: Machina records author geometry, adapters render resolved rectangles in host primitives.
|
|
260
|
+
- Reinforce stable component registries (`views`) plus dynamic `viewData`/`nodeData` channels across React, React Native, and Vue.
|
|
261
|
+
|
|
262
|
+
## 11) Migration / compatibility notes
|
|
263
|
+
|
|
264
|
+
- Do **not** break current root import patterns in immediate work.
|
|
265
|
+
- Maintain:
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
import { MachinaReactView } from "machinalayout";
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
through `0.x`.
|
|
272
|
+
|
|
273
|
+
- Mark subpath imports as preferred forward path.
|
|
274
|
+
- Consider root de-exports only in future major/split-package decision.
|
|
275
|
+
|
|
276
|
+
## 12) Milestone decomposition
|
|
277
|
+
|
|
278
|
+
### A1 — React Native layout adapter
|
|
279
|
+
|
|
280
|
+
Scope:
|
|
281
|
+
|
|
282
|
+
- Add `src/react-native` adapter entry.
|
|
283
|
+
- Add `machinalayout/react-native` subpath export.
|
|
284
|
+
- Add optional `react-native` peer metadata.
|
|
285
|
+
- Add initial RN adapter tests in isolated lane.
|
|
286
|
+
|
|
287
|
+
Prereqs from A0:
|
|
288
|
+
|
|
289
|
+
- Multi-entry build/export plumbing.
|
|
290
|
+
|
|
291
|
+
Status note (A1a, 2026-05-11): multi-entry dist output and subpath exports for existing modules (`./react`, `./text`, `./text/react`) are now being implemented while preserving root-import compatibility during `0.x`.
|
|
292
|
+
|
|
293
|
+
### A2 — React Native text renderer
|
|
294
|
+
|
|
295
|
+
Scope:
|
|
296
|
+
|
|
297
|
+
- Add `src/text/react-native` renderer.
|
|
298
|
+
- Add `machinalayout/text/react-native` subpath export.
|
|
299
|
+
- Extend RN adapter test lane for text renderer behavior.
|
|
300
|
+
|
|
301
|
+
### A3 — Vue layout adapter
|
|
302
|
+
|
|
303
|
+
Scope:
|
|
304
|
+
|
|
305
|
+
- Add `src/vue` adapter entry.
|
|
306
|
+
- Add `machinalayout/vue` subpath export.
|
|
307
|
+
- Add optional `vue` peer metadata.
|
|
308
|
+
- Add Vue adapter tests in isolated lane.
|
|
309
|
+
|
|
310
|
+
### A4 — Vue text renderer
|
|
311
|
+
|
|
312
|
+
Scope:
|
|
313
|
+
|
|
314
|
+
- Add `src/text/vue` renderer.
|
|
315
|
+
- Add `machinalayout/text/vue` subpath export.
|
|
316
|
+
- Extend Vue test lane for text rendering behavior.
|
|
317
|
+
|
|
318
|
+
### Later adapters
|
|
319
|
+
|
|
320
|
+
- SVG/debug renderer under dedicated subpaths.
|
|
321
|
+
- Svelte/Solid exploration after adapter API stabilization.
|
|
322
|
+
|
|
323
|
+
## 13) Risks and mitigations
|
|
324
|
+
|
|
325
|
+
1. **Root export bloat and accidental framework coupling**
|
|
326
|
+
- Mitigation: keep new adapters subpath-only; avoid root re-exports for new frameworks.
|
|
327
|
+
|
|
328
|
+
2. **Peer dependency confusion**
|
|
329
|
+
- Mitigation: explicit matrix in README (adapter → required peer).
|
|
330
|
+
|
|
331
|
+
3. **Build complexity regression**
|
|
332
|
+
- Mitigation: explicit multi-entry manifest + pack smoke checks per milestone.
|
|
333
|
+
|
|
334
|
+
4. **CI/test instability from heavy adapter stacks**
|
|
335
|
+
- Mitigation: separate adapter test lanes and scoped test commands.
|
|
336
|
+
|
|
337
|
+
5. **Future package split cost**
|
|
338
|
+
- Mitigation: enforce subpath discipline now so split is mostly import-path and publish-surface work later.
|
|
339
|
+
|
|
340
|
+
## 14) Exact verification commands run
|
|
341
|
+
|
|
342
|
+
From repository root:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
npm test
|
|
346
|
+
npm run build
|
|
347
|
+
cd samples/control-room && npm run build
|
|
348
|
+
cd samples/music-player && npm run build
|
|
349
|
+
npm pack --dry-run
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
Observed result in A0: all commands completed successfully in this environment.
|
package/docs/adapters.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Adapter overview
|
|
2
|
+
|
|
3
|
+
Machina adapters ask you to learn one layout model: Machina records. The framework adapter only asks for components in that framework.
|
|
4
|
+
|
|
5
|
+
Layout geometry stays in `LayoutRow[]` + resolved rectangles from core APIs. Adapter differences are host-renderer details (DOM versus React Native style primitives), not separate layout dialects.
|
|
6
|
+
|
|
7
|
+
## Adapter + text renderer matrix
|
|
8
|
+
|
|
9
|
+
| Target | Layout adapter | Text renderer | Required peer(s) | Notes |
|
|
10
|
+
| --- | --- | --- | --- | --- |
|
|
11
|
+
| React DOM | `machinalayout/react` | `machinalayout/text/react` | `react`, `react-dom` | Supports DOM containment/content-visibility and DOM wrapper hooks (`className`/`style`, attrs). |
|
|
12
|
+
| React Native | `machinalayout/react-native` | `machinalayout/text/react-native` | `react`, `react-native` | Uses numeric RN styles and RN primitives (`View`/`Text`); no DOM containment/content-visibility. |
|
|
13
|
+
| Vue DOM | `machinalayout/vue` | `machinalayout/text/vue` | `vue` | Adapter uses `h()` internally; users keep normal Vue components/templates as payloads. |
|
|
14
|
+
|
|
15
|
+
## Import guidance
|
|
16
|
+
|
|
17
|
+
- Subpath imports are preferred for adapters/renderers: `machinalayout/react`, `machinalayout/react-native`, `machinalayout/vue`, `machinalayout/text`, `machinalayout/text/react`, `machinalayout/text/react-native`, and `machinalayout/text/vue`.
|
|
18
|
+
- Root imports remain valid during `0.x` compatibility windows.
|
|
19
|
+
- Framework peers are adapter-specific: install only peers needed by the subpaths you use.
|