@mapples/codegen 0.2.0-beta.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 +16 -0
- package/dist/edits.d.ts +9 -0
- package/dist/edits.js +127 -0
- package/dist/edits.js.map +1 -0
- package/dist/emit.d.ts +35 -0
- package/dist/emit.js +154 -0
- package/dist/emit.js.map +1 -0
- package/dist/imports.d.ts +17 -0
- package/dist/imports.js +117 -0
- package/dist/imports.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/instances.d.ts +33 -0
- package/dist/instances.js +139 -0
- package/dist/instances.js.map +1 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.js +42 -0
- package/dist/paths.js.map +1 -0
- package/dist/props.d.ts +22 -0
- package/dist/props.js +52 -0
- package/dist/props.js.map +1 -0
- package/dist/styles.d.ts +11 -0
- package/dist/styles.js +131 -0
- package/dist/styles.js.map +1 -0
- package/package.json +24 -0
package/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# @mapples/codegen
|
|
2
|
+
|
|
3
|
+
Pure RenderDom → TSX generation for Mapples pages and components — the half of
|
|
4
|
+
the `mapples` CLI's code generation that has no I/O, so the Creator's in-app
|
|
5
|
+
code editor and the CLI print the same file from the same document.
|
|
6
|
+
|
|
7
|
+
- `emitPage` / `emitComponent` / `emitTree`: a whole file (unformatted — run
|
|
8
|
+
Prettier yourself; the CLI does, with the project's own config).
|
|
9
|
+
- `collectImports` / `printImports` / `importNeedsFor`: the import block.
|
|
10
|
+
- `hoistStyles`: every `styled` object becomes a `Styler.create` entry.
|
|
11
|
+
- `instanceLinker`: file language (`Custom` + relative import) ↔ canvas
|
|
12
|
+
language (`ComponentInstance`) for linked Creator components, over an
|
|
13
|
+
injected module resolver (`posixResolver` for repo-relative paths).
|
|
14
|
+
- Route markers: `ROUTE_MARKER`, `withRouteMarker`, `withoutRouteMarker`.
|
|
15
|
+
|
|
16
|
+
Depends only on `@mapples/sid-ast`.
|
package/dist/edits.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type RenderDomNode, type SidEdit } from '@mapples/sid-ast';
|
|
2
|
+
export interface IndexedNode {
|
|
3
|
+
node: RenderDomNode;
|
|
4
|
+
parentSid: string | null;
|
|
5
|
+
index: number;
|
|
6
|
+
}
|
|
7
|
+
/** Every node of a tree by sid, with its parent and position. */
|
|
8
|
+
export declare function indexTree(root: RenderDomNode | null): Map<string, IndexedNode>;
|
|
9
|
+
export declare function treeToEdits(local: RenderDomNode | null, merged: RenderDomNode | null): SidEdit[];
|
package/dist/edits.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// Translate "the file currently shows `local`, it should show `merged`" into
|
|
2
|
+
// surgical SidEdits for @mapples/sid-ast — so document changes land in a
|
|
3
|
+
// file without touching the code around the elements. Edit order matters:
|
|
4
|
+
// removals first (so a reparented sid is gone before its new parent inserts
|
|
5
|
+
// it), then shell updates, insertions, and reorders.
|
|
6
|
+
import { deepEqual } from '@mapples/sid-ast';
|
|
7
|
+
/** Every node of a tree by sid, with its parent and position. */
|
|
8
|
+
export function indexTree(root) {
|
|
9
|
+
const map = new Map();
|
|
10
|
+
const walk = (node, parentSid, index) => {
|
|
11
|
+
if (map.has(node.sid)) {
|
|
12
|
+
throw new Error(`duplicate sid in tree: ${node.sid}`);
|
|
13
|
+
}
|
|
14
|
+
map.set(node.sid, { node, parentSid, index });
|
|
15
|
+
node.children.forEach((child, i) => walk(child, node.sid, i));
|
|
16
|
+
};
|
|
17
|
+
if (root)
|
|
18
|
+
walk(root, null, 0);
|
|
19
|
+
return map;
|
|
20
|
+
}
|
|
21
|
+
/** `{refProps, dataProps, actionProps}` of a node, present only when non-empty. */
|
|
22
|
+
function sidecarOf(node) {
|
|
23
|
+
const out = {};
|
|
24
|
+
if (node.refProps && Object.keys(node.refProps).length > 0)
|
|
25
|
+
out.refProps = node.refProps;
|
|
26
|
+
if (node.dataProps && Object.keys(node.dataProps).length > 0)
|
|
27
|
+
out.dataProps = node.dataProps;
|
|
28
|
+
if (node.actionProps && Object.keys(node.actionProps).length > 0) {
|
|
29
|
+
out.actionProps = node.actionProps;
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
/** The same fields with `{}` standing in for absence — the comparison shape. */
|
|
34
|
+
function sidecarFilled(node) {
|
|
35
|
+
return {
|
|
36
|
+
refProps: node.refProps ?? {},
|
|
37
|
+
dataProps: node.dataProps ?? {},
|
|
38
|
+
actionProps: node.actionProps ?? {},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function treeToEdits(local, merged) {
|
|
42
|
+
const lIdx = indexTree(local);
|
|
43
|
+
const mIdx = indexTree(merged);
|
|
44
|
+
if (local && merged && local.sid !== merged.sid) {
|
|
45
|
+
// Root replaced: one subtree swap.
|
|
46
|
+
return [{ kind: 'replaceSubtree', sid: local.sid, node: merged }];
|
|
47
|
+
}
|
|
48
|
+
const removes = [];
|
|
49
|
+
const shells = [];
|
|
50
|
+
const inserts = [];
|
|
51
|
+
const moves = [];
|
|
52
|
+
// Removals: local nodes that vanished from merged, or were reparented (their
|
|
53
|
+
// new parent re-inserts the merged subtree). Only topmost removals needed.
|
|
54
|
+
for (const [sid, lEntry] of lIdx) {
|
|
55
|
+
const parentRemoved = lEntry.parentSid !== null &&
|
|
56
|
+
(!mIdx.has(lEntry.parentSid) ||
|
|
57
|
+
(lIdx.has(lEntry.parentSid) && removedOrReparented(lEntry.parentSid, lIdx, mIdx)));
|
|
58
|
+
if (parentRemoved)
|
|
59
|
+
continue;
|
|
60
|
+
if (removedOrReparented(sid, lIdx, mIdx)) {
|
|
61
|
+
removes.push({ kind: 'removeNode', sid });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Is this local node (or an ancestor) getting removed/re-inserted wholesale?
|
|
65
|
+
const insideRemoved = (sid) => {
|
|
66
|
+
let cursor = sid;
|
|
67
|
+
while (cursor !== null) {
|
|
68
|
+
if (removedOrReparented(cursor, lIdx, mIdx))
|
|
69
|
+
return true;
|
|
70
|
+
cursor = lIdx.get(cursor)?.parentSid ?? null;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
};
|
|
74
|
+
for (const [sid, mEntry] of mIdx) {
|
|
75
|
+
const lEntry = lIdx.get(sid);
|
|
76
|
+
if (lEntry && !insideRemoved(sid)) {
|
|
77
|
+
const typeChanged = lEntry.node.type !== mEntry.node.type;
|
|
78
|
+
const sidecarChanged = !deepEqual(sidecarFilled(lEntry.node), sidecarFilled(mEntry.node));
|
|
79
|
+
if (typeChanged || sidecarChanged || !deepEqual(lEntry.node.props, mEntry.node.props)) {
|
|
80
|
+
shells.push({
|
|
81
|
+
kind: 'setProps',
|
|
82
|
+
sid,
|
|
83
|
+
props: mEntry.node.props,
|
|
84
|
+
...(typeChanged ? { type: mEntry.node.type } : {}),
|
|
85
|
+
...sidecarOf(mEntry.node),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Insertions + reorders per parent present in both trees.
|
|
91
|
+
for (const [sid, mEntry] of mIdx) {
|
|
92
|
+
const lEntry = lIdx.get(sid);
|
|
93
|
+
if (!lEntry || insideRemoved(sid))
|
|
94
|
+
continue;
|
|
95
|
+
const lKids = lEntry.node.children.map((c) => c.sid);
|
|
96
|
+
const mKids = mEntry.node.children.map((c) => c.sid);
|
|
97
|
+
for (const kid of mKids) {
|
|
98
|
+
const isChildHereAlready = lKids.includes(kid) && !removedOrReparented(kid, lIdx, mIdx);
|
|
99
|
+
if (!isChildHereAlready) {
|
|
100
|
+
inserts.push({
|
|
101
|
+
kind: 'insertChild',
|
|
102
|
+
parentSid: sid,
|
|
103
|
+
at: mKids.indexOf(kid),
|
|
104
|
+
node: mIdx.get(kid).node,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const surviving = lKids.filter((k) => mKids.includes(k) && !removedOrReparented(k, lIdx, mIdx));
|
|
109
|
+
const targetOrder = mKids.filter((k) => surviving.includes(k));
|
|
110
|
+
if (!deepEqual(surviving, targetOrder)) {
|
|
111
|
+
for (let i = 0; i < mKids.length; i++) {
|
|
112
|
+
moves.push({ kind: 'moveChild', parentSid: sid, sid: mKids[i], to: i });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return [...removes, ...shells, ...inserts, ...moves];
|
|
117
|
+
}
|
|
118
|
+
function removedOrReparented(sid, lIdx, mIdx) {
|
|
119
|
+
const lEntry = lIdx.get(sid);
|
|
120
|
+
const mEntry = mIdx.get(sid);
|
|
121
|
+
if (!lEntry)
|
|
122
|
+
return false;
|
|
123
|
+
if (!mEntry)
|
|
124
|
+
return true;
|
|
125
|
+
return lEntry.parentSid !== mEntry.parentSid;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=edits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edits.js","sourceRoot":"","sources":["../src/edits.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,yEAAyE;AACzE,0EAA0E;AAC1E,4EAA4E;AAC5E,qDAAqD;AAErD,OAAO,EAAE,SAAS,EAAoC,MAAM,kBAAkB,CAAC;AAQ/E,iEAAiE;AACjE,MAAM,UAAU,SAAS,CAAC,IAA0B;IAClD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC3C,MAAM,IAAI,GAAG,CAAC,IAAmB,EAAE,SAAwB,EAAE,KAAa,EAAQ,EAAE;QAClF,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC;IACF,IAAI,IAAI;QAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9B,OAAO,GAAG,CAAC;AACb,CAAC;AAID,mFAAmF;AACnF,SAAS,SAAS,CAAC,IAAa;IAC9B,MAAM,GAAG,GAAY,EAAE,CAAC;IACxB,IAAI,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IACzF,IAAI,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAC7F,IAAI,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACrC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,SAAS,aAAa,CAAC,IAAa;IAClC,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,EAAE;QAC7B,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;QAC/B,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;KACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAA2B,EAAE,MAA4B;IACnF,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAE/B,IAAI,KAAK,IAAI,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC;QAChD,mCAAmC;QACnC,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAc,EAAE,CAAC;IAE5B,6EAA6E;IAC7E,2EAA2E;IAC3E,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACjC,MAAM,aAAa,GACjB,MAAM,CAAC,SAAS,KAAK,IAAI;YACzB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;gBAC1B,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,mBAAmB,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACvF,IAAI,aAAa;YAAE,SAAS;QAC5B,IAAI,mBAAmB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,MAAM,aAAa,GAAG,CAAC,GAAW,EAAW,EAAE;QAC7C,IAAI,MAAM,GAAkB,GAAG,CAAC;QAChC,OAAO,MAAM,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;YACzD,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,SAAS,IAAI,IAAI,CAAC;QAC/C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YAC1D,MAAM,cAAc,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YAC1F,IAAI,WAAW,IAAI,cAAc,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtF,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,UAAU;oBAChB,GAAG;oBACH,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK;oBACxB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAClD,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC;iBAC1B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,0DAA0D;IAC1D,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,IAAI,aAAa,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAErD,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,MAAM,kBAAkB,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YACxF,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,aAAa;oBACnB,SAAS,EAAE,GAAG;oBACd,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;oBACtB,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,IAAI;iBAC1B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAChG,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;YACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,mBAAmB,CAC1B,GAAW,EACX,IAA8B,EAC9B,IAA8B;IAE9B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO,MAAM,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,CAAC;AAC/C,CAAC"}
|
package/dist/emit.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type RenderDomNode } from '@mapples/sid-ast';
|
|
2
|
+
export declare const GENERATED_HEADER: string;
|
|
3
|
+
/** `// mapples-route: <id> — “<name>”` — the first such line names the route a file renders. */
|
|
4
|
+
export declare const ROUTE_MARKER: RegExp;
|
|
5
|
+
export declare function routeMarkerLine(routeId: string, routeName: string): string;
|
|
6
|
+
export declare function readRouteMarker(source: string): string | null;
|
|
7
|
+
/** Ensure `source` opens with the marker for `routeId`; replaces a stale marker, never duplicates. */
|
|
8
|
+
export declare function withRouteMarker(source: string, routeId: string, routeName: string): string;
|
|
9
|
+
export declare function withoutRouteMarker(source: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* The exported component name for a page: the page name in PascalCase, with
|
|
12
|
+
* no suffix. `taken` lists identifiers the file already imports (a page named
|
|
13
|
+
* “View” must not shadow the `View` it renders) — a collision gets `Screen`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function pageComponentName(pageName: string, taken?: Iterable<string>,
|
|
16
|
+
/** Appended when the name is taken or reserved: a page becomes `…Screen`, a component `…Component`. */
|
|
17
|
+
suffix?: 'Screen' | 'Component'): string;
|
|
18
|
+
export interface EmitPageInput {
|
|
19
|
+
name: string;
|
|
20
|
+
root: RenderDomNode;
|
|
21
|
+
/** Present for a routed page: the file opens with its route marker. */
|
|
22
|
+
route?: {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export declare function emitPage(page: EmitPageInput): string;
|
|
28
|
+
export declare const COMPONENT_HEADER: string;
|
|
29
|
+
export interface EmitComponentInput {
|
|
30
|
+
name: string;
|
|
31
|
+
root: RenderDomNode;
|
|
32
|
+
}
|
|
33
|
+
/** A Creator component as a file: same shape as a page, no route. */
|
|
34
|
+
export declare function emitComponent(component: EmitComponentInput): string;
|
|
35
|
+
export declare function emitTree(name: string, root: RenderDomNode, leading: string[], header?: string, suffix?: 'Screen' | 'Component'): string;
|
package/dist/emit.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// RenderDom page -> complete page file. Deterministic: stable prop order
|
|
2
|
+
// (sid-ast printer), stable import order. Unformatted — the caller runs
|
|
3
|
+
// Prettier (the CLI with the project's own config, the Creator standalone).
|
|
4
|
+
//
|
|
5
|
+
// A page file lives where expo-router expects the route (RFC-0002 §5 file
|
|
6
|
+
// layout): `app/<segment>.tsx` for a routed page, `<pagesDir>/<Name>.tsx` for
|
|
7
|
+
// a page that is not in the navigation yet. Routed files open with a route
|
|
8
|
+
// marker line that carries the route id — the file's identity for renames.
|
|
9
|
+
import { printNode, printValue } from '@mapples/sid-ast';
|
|
10
|
+
import { collectImports, printImports } from './imports.js';
|
|
11
|
+
import { hoistStyles, STYLE_MODULE } from './styles.js';
|
|
12
|
+
export const GENERATED_HEADER = '// Generated by Mapples — edit freely, but keep the $sid props intact.\n' +
|
|
13
|
+
'// Two-way sync: `mapples sync` reconciles this file with Mapples Creator.';
|
|
14
|
+
/** `// mapples-route: <id> — “<name>”` — the first such line names the route a file renders. */
|
|
15
|
+
export const ROUTE_MARKER = /\/\/\s*mapples-route:\s*([A-Za-z0-9_-]+)/;
|
|
16
|
+
export function routeMarkerLine(routeId, routeName) {
|
|
17
|
+
return `// mapples-route: ${routeId} — “${routeName}”. Renaming this file renames the route in Creator on the next \`mapples sync\`.`;
|
|
18
|
+
}
|
|
19
|
+
export function readRouteMarker(source) {
|
|
20
|
+
return ROUTE_MARKER.exec(source)?.[1] ?? null;
|
|
21
|
+
}
|
|
22
|
+
/** Ensure `source` opens with the marker for `routeId`; replaces a stale marker, never duplicates. */
|
|
23
|
+
export function withRouteMarker(source, routeId, routeName) {
|
|
24
|
+
const line = routeMarkerLine(routeId, routeName);
|
|
25
|
+
const lines = source.split('\n');
|
|
26
|
+
const idx = lines.findIndex((l) => ROUTE_MARKER.test(l));
|
|
27
|
+
if (idx === -1)
|
|
28
|
+
return `${line}\n${source}`;
|
|
29
|
+
if (lines[idx] === line)
|
|
30
|
+
return source;
|
|
31
|
+
lines[idx] = line;
|
|
32
|
+
return lines.join('\n');
|
|
33
|
+
}
|
|
34
|
+
export function withoutRouteMarker(source) {
|
|
35
|
+
const lines = source.split('\n');
|
|
36
|
+
const idx = lines.findIndex((l) => ROUTE_MARKER.test(l));
|
|
37
|
+
if (idx === -1)
|
|
38
|
+
return source;
|
|
39
|
+
lines.splice(idx, 1);
|
|
40
|
+
// A marker was followed by its own blank line; drop it so the file does not grow a gap.
|
|
41
|
+
if (idx === 0 && lines[0] === '')
|
|
42
|
+
lines.shift();
|
|
43
|
+
return lines.join('\n');
|
|
44
|
+
}
|
|
45
|
+
const RESERVED = new Set([
|
|
46
|
+
'default',
|
|
47
|
+
'function',
|
|
48
|
+
'class',
|
|
49
|
+
'return',
|
|
50
|
+
'export',
|
|
51
|
+
'import',
|
|
52
|
+
'new',
|
|
53
|
+
'delete',
|
|
54
|
+
'in',
|
|
55
|
+
'of',
|
|
56
|
+
'for',
|
|
57
|
+
'if',
|
|
58
|
+
'else',
|
|
59
|
+
'switch',
|
|
60
|
+
'case',
|
|
61
|
+
'while',
|
|
62
|
+
'do',
|
|
63
|
+
'var',
|
|
64
|
+
'let',
|
|
65
|
+
'const',
|
|
66
|
+
'this',
|
|
67
|
+
'super',
|
|
68
|
+
'null',
|
|
69
|
+
'true',
|
|
70
|
+
'false',
|
|
71
|
+
'void',
|
|
72
|
+
'typeof',
|
|
73
|
+
'with',
|
|
74
|
+
'yield',
|
|
75
|
+
'await',
|
|
76
|
+
'enum',
|
|
77
|
+
'extends',
|
|
78
|
+
'try',
|
|
79
|
+
'catch',
|
|
80
|
+
'finally',
|
|
81
|
+
'throw',
|
|
82
|
+
'break',
|
|
83
|
+
'continue',
|
|
84
|
+
'debugger',
|
|
85
|
+
'instanceof',
|
|
86
|
+
'static',
|
|
87
|
+
'interface',
|
|
88
|
+
'package',
|
|
89
|
+
'private',
|
|
90
|
+
'protected',
|
|
91
|
+
'public',
|
|
92
|
+
'implements',
|
|
93
|
+
]);
|
|
94
|
+
/**
|
|
95
|
+
* The exported component name for a page: the page name in PascalCase, with
|
|
96
|
+
* no suffix. `taken` lists identifiers the file already imports (a page named
|
|
97
|
+
* “View” must not shadow the `View` it renders) — a collision gets `Screen`.
|
|
98
|
+
*/
|
|
99
|
+
export function pageComponentName(pageName, taken = [],
|
|
100
|
+
/** Appended when the name is taken or reserved: a page becomes `…Screen`, a component `…Component`. */
|
|
101
|
+
suffix = 'Screen') {
|
|
102
|
+
let pascal = pageName
|
|
103
|
+
.split(/[^A-Za-z0-9]+/)
|
|
104
|
+
.filter(Boolean)
|
|
105
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
106
|
+
.join('');
|
|
107
|
+
if (pascal === '' || /^[0-9]/.test(pascal))
|
|
108
|
+
pascal = `Page${pascal}`;
|
|
109
|
+
const used = new Set(taken);
|
|
110
|
+
if (used.has(pascal) || RESERVED.has(pascal.toLowerCase()))
|
|
111
|
+
pascal = `${pascal}${suffix}`;
|
|
112
|
+
return pascal;
|
|
113
|
+
}
|
|
114
|
+
export function emitPage(page) {
|
|
115
|
+
return emitTree(page.name, page.root, page.route ? [routeMarkerLine(page.route.id, page.route.name)] : []);
|
|
116
|
+
}
|
|
117
|
+
export const COMPONENT_HEADER = '// Generated by Mapples — a Creator component. Edit freely, keep the $sid props intact.\n' +
|
|
118
|
+
'// Two-way sync: `mapples sync` reconciles this file with Mapples Creator.';
|
|
119
|
+
/** A Creator component as a file: same shape as a page, no route. */
|
|
120
|
+
export function emitComponent(component) {
|
|
121
|
+
return emitTree(component.name, component.root, [], COMPONENT_HEADER, 'Component');
|
|
122
|
+
}
|
|
123
|
+
export function emitTree(name, root, leading, header = GENERATED_HEADER, suffix = 'Screen') {
|
|
124
|
+
const imports = collectImports(root);
|
|
125
|
+
// Styles live in a `Styler.create` dictionary below the component, the way
|
|
126
|
+
// hand-written Mapples code keeps them — never inline in the JSX.
|
|
127
|
+
const styles = hoistStyles(root);
|
|
128
|
+
const jsx = printNode(root, ' ', { styleRef: styles.refFor });
|
|
129
|
+
const componentName = pageComponentName(name, [...imports.uiNames, ...imports.customs.keys(), styles.dictName, 'Styler'], suffix);
|
|
130
|
+
const code = [
|
|
131
|
+
...leading,
|
|
132
|
+
header,
|
|
133
|
+
'',
|
|
134
|
+
printImports(imports),
|
|
135
|
+
...(styles.entries.length > 0 ? [`import { Styler } from '${STYLE_MODULE}';`] : []),
|
|
136
|
+
'',
|
|
137
|
+
`export default function ${componentName}() {`,
|
|
138
|
+
' return (',
|
|
139
|
+
jsx,
|
|
140
|
+
' );',
|
|
141
|
+
'}',
|
|
142
|
+
...(styles.entries.length > 0
|
|
143
|
+
? [
|
|
144
|
+
'',
|
|
145
|
+
`const ${styles.dictName} = Styler.create({`,
|
|
146
|
+
...styles.entries.map(([key, value]) => ` ${key}: ${printValue(value)},`),
|
|
147
|
+
'});',
|
|
148
|
+
]
|
|
149
|
+
: []),
|
|
150
|
+
'',
|
|
151
|
+
].join('\n');
|
|
152
|
+
return code;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=emit.js.map
|
package/dist/emit.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../src/emit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ImportNeed, RenderDomNode } from '@mapples/sid-ast';
|
|
2
|
+
export interface ResolvedImports {
|
|
3
|
+
uiNames: string[];
|
|
4
|
+
customs: Map<string, {
|
|
5
|
+
module: string;
|
|
6
|
+
exportName: string;
|
|
7
|
+
}>;
|
|
8
|
+
}
|
|
9
|
+
export declare const UI_MODULE = "@mapples/ui";
|
|
10
|
+
export declare function parseImportRef(ref: string): {
|
|
11
|
+
module: string;
|
|
12
|
+
exportName: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function collectImports(root: RenderDomNode): ResolvedImports;
|
|
15
|
+
export declare function printImports(resolved: ResolvedImports): string;
|
|
16
|
+
/** ImportNeeds for @mapples/sid-ast upsertImports, from a merged tree. */
|
|
17
|
+
export declare function importNeedsFor(root: RenderDomNode): ImportNeed[];
|
package/dist/imports.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export const UI_MODULE = '@mapples/ui';
|
|
2
|
+
export function parseImportRef(ref) {
|
|
3
|
+
const idx = ref.lastIndexOf('#');
|
|
4
|
+
if (idx === -1)
|
|
5
|
+
throw new Error(`invalid importRef (missing #): ${ref}`);
|
|
6
|
+
return { module: ref.slice(0, idx), exportName: ref.slice(idx + 1) };
|
|
7
|
+
}
|
|
8
|
+
export function collectImports(root) {
|
|
9
|
+
const uiNames = new Set();
|
|
10
|
+
const customs = new Map();
|
|
11
|
+
const walk = (node) => {
|
|
12
|
+
if (node.type === 'Custom') {
|
|
13
|
+
const name = node.props.name;
|
|
14
|
+
const importRef = node.props.importRef;
|
|
15
|
+
if (typeof name !== 'string' || typeof importRef !== 'string') {
|
|
16
|
+
throw new Error(`Custom node ${node.sid} is missing name/importRef`);
|
|
17
|
+
}
|
|
18
|
+
const origin = parseImportRef(importRef);
|
|
19
|
+
if (origin.module === '') {
|
|
20
|
+
throw new Error(`Custom node ${node.sid} (${name}) has a local importRef (${importRef}); cannot emit an import for it`);
|
|
21
|
+
}
|
|
22
|
+
const existing = customs.get(name);
|
|
23
|
+
if (existing &&
|
|
24
|
+
(existing.module !== origin.module || existing.exportName !== origin.exportName)) {
|
|
25
|
+
throw new Error(`Custom name collision: ${name} maps to both ${existing.module} and ${origin.module}`);
|
|
26
|
+
}
|
|
27
|
+
customs.set(name, origin);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
uiNames.add(node.type);
|
|
31
|
+
}
|
|
32
|
+
for (const child of node.children)
|
|
33
|
+
walk(child);
|
|
34
|
+
};
|
|
35
|
+
walk(root);
|
|
36
|
+
for (const name of customs.keys()) {
|
|
37
|
+
if (uiNames.has(name)) {
|
|
38
|
+
throw new Error(`Custom component ${name} collides with a @mapples/ui primitive of the same name`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return { uiNames: [...uiNames].sort(), customs };
|
|
42
|
+
}
|
|
43
|
+
export function printImports(resolved) {
|
|
44
|
+
const lines = [];
|
|
45
|
+
if (resolved.uiNames.length > 0) {
|
|
46
|
+
lines.push(`import { ${resolved.uiNames.join(', ')} } from '${UI_MODULE}';`);
|
|
47
|
+
}
|
|
48
|
+
const byModule = new Map();
|
|
49
|
+
for (const [local, origin] of resolved.customs) {
|
|
50
|
+
let entry = byModule.get(origin.module);
|
|
51
|
+
if (!entry) {
|
|
52
|
+
entry = { defaults: [], named: [] };
|
|
53
|
+
byModule.set(origin.module, entry);
|
|
54
|
+
}
|
|
55
|
+
if (origin.exportName === 'default')
|
|
56
|
+
entry.defaults.push(local);
|
|
57
|
+
else
|
|
58
|
+
entry.named.push([origin.exportName, local]);
|
|
59
|
+
}
|
|
60
|
+
for (const module of [...byModule.keys()].sort()) {
|
|
61
|
+
const entry = byModule.get(module);
|
|
62
|
+
const pieces = [];
|
|
63
|
+
if (entry.defaults.length > 1) {
|
|
64
|
+
throw new Error(`two default imports from ${module}: ${entry.defaults.join(', ')}`);
|
|
65
|
+
}
|
|
66
|
+
if (entry.defaults.length === 1)
|
|
67
|
+
pieces.push(entry.defaults[0]);
|
|
68
|
+
if (entry.named.length > 0) {
|
|
69
|
+
const named = entry.named
|
|
70
|
+
.sort(([a], [b]) => (a < b ? -1 : 1))
|
|
71
|
+
.map(([exp, local]) => (exp === local ? exp : `${exp} as ${local}`))
|
|
72
|
+
.join(', ');
|
|
73
|
+
pieces.push(`{ ${named} }`);
|
|
74
|
+
}
|
|
75
|
+
lines.push(`import ${pieces.join(', ')} from '${module}';`);
|
|
76
|
+
}
|
|
77
|
+
return lines.join('\n');
|
|
78
|
+
}
|
|
79
|
+
/** ImportNeeds for @mapples/sid-ast upsertImports, from a merged tree. */
|
|
80
|
+
export function importNeedsFor(root) {
|
|
81
|
+
const { uiNames, customs } = collectImportsTolerant(root);
|
|
82
|
+
const needs = [];
|
|
83
|
+
if (uiNames.length > 0)
|
|
84
|
+
needs.push({ module: UI_MODULE, named: uiNames });
|
|
85
|
+
for (const [local, origin] of customs) {
|
|
86
|
+
if (origin.module === '')
|
|
87
|
+
continue; // locally-defined component: nothing to import
|
|
88
|
+
needs.push(origin.exportName === 'default'
|
|
89
|
+
? { module: origin.module, defaultName: local }
|
|
90
|
+
: { module: origin.module, named: [origin.exportName] });
|
|
91
|
+
}
|
|
92
|
+
return needs;
|
|
93
|
+
}
|
|
94
|
+
/** Like collectImports but tolerant of local (#Name) customs — used for healing. */
|
|
95
|
+
function collectImportsTolerant(root) {
|
|
96
|
+
const uiNames = new Set();
|
|
97
|
+
const customs = new Map();
|
|
98
|
+
const walk = (node) => {
|
|
99
|
+
if (node.type === 'Custom') {
|
|
100
|
+
const name = node.props.name;
|
|
101
|
+
const importRef = node.props.importRef;
|
|
102
|
+
if (typeof name === 'string' && typeof importRef === 'string') {
|
|
103
|
+
const origin = parseImportRef(importRef);
|
|
104
|
+
if (!customs.has(name))
|
|
105
|
+
customs.set(name, origin);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
uiNames.add(node.type);
|
|
110
|
+
}
|
|
111
|
+
for (const child of node.children)
|
|
112
|
+
walk(child);
|
|
113
|
+
};
|
|
114
|
+
walk(root);
|
|
115
|
+
return { uiNames: [...uiNames].sort(), customs };
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=imports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imports.js","sourceRoot":"","sources":["../src/imports.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { COMPONENT_HEADER, emitComponent, emitPage, emitTree, GENERATED_HEADER, pageComponentName, readRouteMarker, ROUTE_MARKER, routeMarkerLine, withoutRouteMarker, withRouteMarker, type EmitComponentInput, type EmitPageInput, } from './emit.js';
|
|
2
|
+
export { collectImports, importNeedsFor, parseImportRef, printImports, UI_MODULE, type ResolvedImports, } from './imports.js';
|
|
3
|
+
export { hoistStyles, STYLE_MODULE, type HoistedStyles } from './styles.js';
|
|
4
|
+
export { instanceLinker, posixResolver, type ComponentFile, type InstanceLinker, type LinkableComponent, type ModuleResolver, } from './instances.js';
|
|
5
|
+
export { dirname, join, normalize, relative } from './paths.js';
|
|
6
|
+
export { indexTree, treeToEdits, type IndexedNode } from './edits.js';
|
|
7
|
+
export { instancePropsDef, labelFor, type InstancePropKind, type InstancePropSpec, type InstancePropsDef, } from './props.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { COMPONENT_HEADER, emitComponent, emitPage, emitTree, GENERATED_HEADER, pageComponentName, readRouteMarker, ROUTE_MARKER, routeMarkerLine, withoutRouteMarker, withRouteMarker, } from './emit.js';
|
|
2
|
+
export { collectImports, importNeedsFor, parseImportRef, printImports, UI_MODULE, } from './imports.js';
|
|
3
|
+
export { hoistStyles, STYLE_MODULE } from './styles.js';
|
|
4
|
+
export { instanceLinker, posixResolver, } from './instances.js';
|
|
5
|
+
export { dirname, join, normalize, relative } from './paths.js';
|
|
6
|
+
export { indexTree, treeToEdits } from './edits.js';
|
|
7
|
+
export { instancePropsDef, labelFor, } from './props.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,eAAe,GAGhB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,SAAS,GAEV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAsB,MAAM,aAAa,CAAC;AAC5E,OAAO,EACL,cAAc,EACd,aAAa,GAKd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAoB,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,gBAAgB,EAChB,QAAQ,GAIT,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ExtractWarning, RenderDomNode } from '@mapples/sid-ast';
|
|
2
|
+
export interface InstanceLinker {
|
|
3
|
+
/** File language -> canvas language, in place. Reports what could not link. */
|
|
4
|
+
link(dom: RenderDomNode, file: string, warn: (w: ExtractWarning) => void): void;
|
|
5
|
+
/** Canvas language -> file language, as a copy. Reports instances with no component. */
|
|
6
|
+
unlink(dom: RenderDomNode, file: string, warn: (w: ExtractWarning) => void): RenderDomNode;
|
|
7
|
+
/** Does this import, from this file, name a managed component? */
|
|
8
|
+
isLinked(origin: {
|
|
9
|
+
module: string;
|
|
10
|
+
exportName: string;
|
|
11
|
+
}, file: string): boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Where a Creator component's file lives (the CLI's `.mapples/components.json` row). */
|
|
14
|
+
export interface ComponentFile {
|
|
15
|
+
file: string;
|
|
16
|
+
name: string;
|
|
17
|
+
}
|
|
18
|
+
/** What the linker needs to know about a Creator component. */
|
|
19
|
+
export interface LinkableComponent {
|
|
20
|
+
name: string;
|
|
21
|
+
/** The Creator component uuid a page's `ComponentInstance` links to. */
|
|
22
|
+
uuid?: string;
|
|
23
|
+
}
|
|
24
|
+
/** Relative-import arithmetic between a page file and a component file. */
|
|
25
|
+
export interface ModuleResolver {
|
|
26
|
+
/** `../mapples/components/ProfileCard` from `app/profile.tsx` -> `mapples/components/ProfileCard.tsx`; null for a bare module. */
|
|
27
|
+
fileFor(fromFile: string, module: string): string | null;
|
|
28
|
+
/** `mapples/components/ProfileCard.tsx` from `app/profile.tsx` -> `../mapples/components/ProfileCard`. */
|
|
29
|
+
moduleFor(fromFile: string, targetFile: string): string;
|
|
30
|
+
}
|
|
31
|
+
/** Repo-relative POSIX paths, no filesystem. */
|
|
32
|
+
export declare const posixResolver: ModuleResolver;
|
|
33
|
+
export declare function instanceLinker(componentsMap: Record<string, ComponentFile>, components: Map<string, LinkableComponent>, resolver?: ModuleResolver): InstanceLinker;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Linked component instances: the two languages a page speaks.
|
|
2
|
+
//
|
|
3
|
+
// In a FILE, a Creator component used on a page is what a developer writes —
|
|
4
|
+
// `import ProfileCard from '../mapples/components/ProfileCard'` and
|
|
5
|
+
// `<ProfileCard $sid="…" styled={{ … }} />` — which extraction reads as a
|
|
6
|
+
// `Custom` node with that import ref. On the CANVAS the same thing is a
|
|
7
|
+
// `ComponentInstance` node: `{ componentUuid, componentName, styled }`, the
|
|
8
|
+
// Creator's linked instance of the saved component. Base and remote trees
|
|
9
|
+
// always speak canvas; a tree read from a file speaks file. `link` and
|
|
10
|
+
// `unlink` convert, so the merge compares like with like and the file never
|
|
11
|
+
// sees a `ComponentInstance` tag (nothing exports one).
|
|
12
|
+
//
|
|
13
|
+
// Paths are whatever the resolver understands: `posixResolver` for
|
|
14
|
+
// repo-relative POSIX paths (the Creator), the CLI plugs in `node:path`.
|
|
15
|
+
import { pageComponentName } from './emit.js';
|
|
16
|
+
import { parseImportRef } from './imports.js';
|
|
17
|
+
import { dirname, join, normalize, relative } from './paths.js';
|
|
18
|
+
/** Repo-relative POSIX paths, no filesystem. */
|
|
19
|
+
export const posixResolver = {
|
|
20
|
+
fileFor(fromFile, module) {
|
|
21
|
+
if (!module.startsWith('.'))
|
|
22
|
+
return null;
|
|
23
|
+
const resolved = normalize(join(dirname(fromFile), module));
|
|
24
|
+
return resolved.endsWith('.tsx') ? resolved : `${resolved}.tsx`;
|
|
25
|
+
},
|
|
26
|
+
moduleFor(fromFile, targetFile) {
|
|
27
|
+
let rel = relative(dirname(fromFile), targetFile).replace(/\.tsx$/, '');
|
|
28
|
+
if (!rel.startsWith('.'))
|
|
29
|
+
rel = `./${rel}`;
|
|
30
|
+
return rel;
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
export function instanceLinker(componentsMap, components, resolver = posixResolver) {
|
|
34
|
+
const byFile = new Map();
|
|
35
|
+
const byUuid = new Map();
|
|
36
|
+
for (const [id, mapping] of Object.entries(componentsMap)) {
|
|
37
|
+
const entity = components.get(id);
|
|
38
|
+
const linked = {
|
|
39
|
+
id,
|
|
40
|
+
file: mapping.file,
|
|
41
|
+
name: entity?.name ?? mapping.name,
|
|
42
|
+
uuid: entity?.uuid,
|
|
43
|
+
};
|
|
44
|
+
byFile.set(linked.file, linked);
|
|
45
|
+
if (linked.uuid)
|
|
46
|
+
byUuid.set(linked.uuid, linked);
|
|
47
|
+
}
|
|
48
|
+
const componentFor = (origin, file) => {
|
|
49
|
+
if (origin.exportName !== 'default')
|
|
50
|
+
return null;
|
|
51
|
+
const target = resolver.fileFor(file, origin.module);
|
|
52
|
+
return target ? (byFile.get(target) ?? null) : null;
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
isLinked: (origin, file) => componentFor(origin, file) !== null,
|
|
56
|
+
link(dom, file, warn) {
|
|
57
|
+
const walk = (node) => {
|
|
58
|
+
node.children.forEach(walk);
|
|
59
|
+
if (node.type !== 'Custom')
|
|
60
|
+
return;
|
|
61
|
+
const { name, importRef, layout } = node.props;
|
|
62
|
+
if (typeof name !== 'string' || typeof importRef !== 'string')
|
|
63
|
+
return;
|
|
64
|
+
const component = componentFor(parseImportRef(importRef), file);
|
|
65
|
+
if (!component)
|
|
66
|
+
return;
|
|
67
|
+
if (!component.uuid) {
|
|
68
|
+
warn({
|
|
69
|
+
kind: 'UNKNOWN_ELEMENT_WITH_SID',
|
|
70
|
+
sid: node.sid,
|
|
71
|
+
detail: `<${name}> is the Creator component “${component.name}”, but that component has no uuid yet — pushed as a Custom placeholder; run \`mapples sync\` again after the component reaches the Creator`,
|
|
72
|
+
});
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Literal props on the tag are the instance's props (the master's
|
|
76
|
+
// signature names them); `styled` keeps its own slot.
|
|
77
|
+
const attrs = (layout ?? {});
|
|
78
|
+
const { styled, ...instanceProps } = attrs;
|
|
79
|
+
if (node.children.length > 0) {
|
|
80
|
+
warn({
|
|
81
|
+
kind: 'NON_LITERAL_PROP',
|
|
82
|
+
sid: node.sid,
|
|
83
|
+
prop: 'children',
|
|
84
|
+
detail: `children of <${name}> are not part of the Creator instance — kept in code only`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
node.type = 'ComponentInstance';
|
|
88
|
+
node.props = {
|
|
89
|
+
...instanceProps,
|
|
90
|
+
componentUuid: component.uuid,
|
|
91
|
+
componentName: component.name,
|
|
92
|
+
...(styled !== undefined ? { styled } : {}),
|
|
93
|
+
};
|
|
94
|
+
node.children = [];
|
|
95
|
+
};
|
|
96
|
+
walk(dom);
|
|
97
|
+
},
|
|
98
|
+
unlink(dom, file, warn) {
|
|
99
|
+
// A component the Creator named after its root ("View", "Button"…)
|
|
100
|
+
// cannot share a local name with the primitive the file imports.
|
|
101
|
+
const primitiveTypes = new Set();
|
|
102
|
+
const collectTypes = (node) => {
|
|
103
|
+
if (node.type !== 'Custom' && node.type !== 'ComponentInstance') {
|
|
104
|
+
primitiveTypes.add(node.type);
|
|
105
|
+
}
|
|
106
|
+
node.children.forEach(collectTypes);
|
|
107
|
+
};
|
|
108
|
+
collectTypes(dom);
|
|
109
|
+
const localName = (component) => pageComponentName(component.name, primitiveTypes, 'Component');
|
|
110
|
+
const convert = (node) => {
|
|
111
|
+
const children = node.children.map(convert);
|
|
112
|
+
if (node.type !== 'ComponentInstance')
|
|
113
|
+
return { ...node, children };
|
|
114
|
+
const { componentUuid, componentName, styled, ...instanceProps } = node.props;
|
|
115
|
+
const component = typeof componentUuid === 'string' ? byUuid.get(componentUuid) : undefined;
|
|
116
|
+
if (!component) {
|
|
117
|
+
warn({
|
|
118
|
+
kind: 'UNKNOWN_ELEMENT_WITH_SID',
|
|
119
|
+
sid: node.sid,
|
|
120
|
+
detail: `instance of component “${String(componentName ?? componentUuid)}” has no component file to import — left as a ComponentInstance tag`,
|
|
121
|
+
});
|
|
122
|
+
return { ...node, children };
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
...node,
|
|
126
|
+
type: 'Custom',
|
|
127
|
+
props: {
|
|
128
|
+
name: localName(component),
|
|
129
|
+
importRef: `${resolver.moduleFor(file, component.file)}#default`,
|
|
130
|
+
layout: { ...instanceProps, ...(styled !== undefined ? { styled } : {}) },
|
|
131
|
+
},
|
|
132
|
+
children,
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
return convert(dom);
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=instances.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instances.js","sourceRoot":"","sources":["../src/instances.ts"],"names":[],"mappings":"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"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function dirname(path: string): string;
|
|
2
|
+
/** Resolve `.`/`..` segments; never escapes above an empty root. */
|
|
3
|
+
export declare function normalize(path: string): string;
|
|
4
|
+
export declare function join(...parts: string[]): string;
|
|
5
|
+
/** `relative('app', 'mapples/components/Card.tsx')` -> `../mapples/components/Card.tsx`. */
|
|
6
|
+
export declare function relative(from: string, to: string): string;
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// POSIX path arithmetic without `node:path`, so the package runs in a browser.
|
|
2
|
+
// Inputs are repo-relative POSIX paths (`app/(mapples)/home.tsx`).
|
|
3
|
+
export function dirname(path) {
|
|
4
|
+
const at = path.lastIndexOf('/');
|
|
5
|
+
return at === -1 ? '.' : at === 0 ? '/' : path.slice(0, at);
|
|
6
|
+
}
|
|
7
|
+
/** Resolve `.`/`..` segments; never escapes above an empty root. */
|
|
8
|
+
export function normalize(path) {
|
|
9
|
+
const out = [];
|
|
10
|
+
for (const segment of path.split('/')) {
|
|
11
|
+
if (segment === '' || segment === '.')
|
|
12
|
+
continue;
|
|
13
|
+
if (segment === '..') {
|
|
14
|
+
if (out.length > 0 && out[out.length - 1] !== '..')
|
|
15
|
+
out.pop();
|
|
16
|
+
else
|
|
17
|
+
out.push('..');
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
out.push(segment);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return (path.startsWith('/') ? '/' : '') + out.join('/');
|
|
24
|
+
}
|
|
25
|
+
export function join(...parts) {
|
|
26
|
+
return normalize(parts.filter((p) => p !== '').join('/'));
|
|
27
|
+
}
|
|
28
|
+
/** `relative('app', 'mapples/components/Card.tsx')` -> `../mapples/components/Card.tsx`. */
|
|
29
|
+
export function relative(from, to) {
|
|
30
|
+
const a = normalize(from)
|
|
31
|
+
.split('/')
|
|
32
|
+
.filter((s) => s !== '' && s !== '.');
|
|
33
|
+
const b = normalize(to)
|
|
34
|
+
.split('/')
|
|
35
|
+
.filter((s) => s !== '' && s !== '.');
|
|
36
|
+
let common = 0;
|
|
37
|
+
while (common < a.length && common < b.length && a[common] === b[common])
|
|
38
|
+
common += 1;
|
|
39
|
+
const up = a.slice(common).map(() => '..');
|
|
40
|
+
return [...up, ...b.slice(common)].join('/');
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AAEnE,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,GAAG;YAAE,SAAS;QAChD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI;gBAAE,GAAG,CAAC,GAAG,EAAE,CAAC;;gBACzD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAG,KAAe;IACrC,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,EAAU;IAC/C,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC;SACtB,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;SACpB,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACxC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,CAAC,CAAC;IACtF,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,CAAC"}
|
package/dist/props.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PropsSignature } from '@mapples/sid-ast';
|
|
2
|
+
export type InstancePropKind = 'text' | 'number' | 'switch' | 'select' | 'code';
|
|
3
|
+
export interface InstancePropSpec {
|
|
4
|
+
key: string;
|
|
5
|
+
/** "Product title" from `productTitle`. */
|
|
6
|
+
label: string;
|
|
7
|
+
kind: InstancePropKind;
|
|
8
|
+
/** The choices of a string-literal union. */
|
|
9
|
+
options?: string[];
|
|
10
|
+
optional: boolean;
|
|
11
|
+
/** The type as written in the file. */
|
|
12
|
+
typeText: string;
|
|
13
|
+
}
|
|
14
|
+
export interface InstancePropsDef {
|
|
15
|
+
fields: InstancePropSpec[];
|
|
16
|
+
/** Function-typed props, in declaration order: the events an instance can wire actions to. */
|
|
17
|
+
actions: string[];
|
|
18
|
+
warnings: string[];
|
|
19
|
+
}
|
|
20
|
+
export declare function labelFor(key: string): string;
|
|
21
|
+
/** Inspector fields and events from a props signature (null → none). */
|
|
22
|
+
export declare function instancePropsDef(signature: PropsSignature | null): InstancePropsDef;
|
package/dist/props.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// A component's declared props as instance fields: what the Creator shows in
|
|
2
|
+
// the inspector for an instance of a component whose file types its props
|
|
3
|
+
// (`function Card({ title, variant }: Props)`), and what the AI is told.
|
|
4
|
+
/** Props the file owns entirely — never instance fields. */
|
|
5
|
+
const RESERVED = new Set(['children', 'style', 'styled']);
|
|
6
|
+
export function labelFor(key) {
|
|
7
|
+
const words = key
|
|
8
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
9
|
+
.replace(/[_-]+/g, ' ')
|
|
10
|
+
.trim()
|
|
11
|
+
.toLowerCase();
|
|
12
|
+
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
13
|
+
}
|
|
14
|
+
/** Inspector fields and events from a props signature (null → none). */
|
|
15
|
+
export function instancePropsDef(signature) {
|
|
16
|
+
const def = { fields: [], actions: [], warnings: [] };
|
|
17
|
+
if (signature === null)
|
|
18
|
+
return def;
|
|
19
|
+
for (const param of signature.params) {
|
|
20
|
+
if (RESERVED.has(param.name))
|
|
21
|
+
continue;
|
|
22
|
+
if (param.kind === 'function') {
|
|
23
|
+
def.actions.push(param.name);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const base = {
|
|
27
|
+
key: param.name,
|
|
28
|
+
label: labelFor(param.name),
|
|
29
|
+
optional: param.optional,
|
|
30
|
+
typeText: param.typeText,
|
|
31
|
+
};
|
|
32
|
+
switch (param.kind) {
|
|
33
|
+
case 'string':
|
|
34
|
+
def.fields.push({ ...base, kind: 'text' });
|
|
35
|
+
break;
|
|
36
|
+
case 'number':
|
|
37
|
+
def.fields.push({ ...base, kind: 'number' });
|
|
38
|
+
break;
|
|
39
|
+
case 'boolean':
|
|
40
|
+
def.fields.push({ ...base, kind: 'switch' });
|
|
41
|
+
break;
|
|
42
|
+
case 'literals':
|
|
43
|
+
def.fields.push({ ...base, kind: 'select', options: param.literals ?? [] });
|
|
44
|
+
break;
|
|
45
|
+
default:
|
|
46
|
+
def.fields.push({ ...base, kind: 'code' });
|
|
47
|
+
def.warnings.push(`prop \`${param.name}\` (${param.typeText}) is edited as JSON — only strings, numbers, booleans, string unions and functions map to inspector controls`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return def;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=props.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"props.js","sourceRoot":"","sources":["../src/props.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,0EAA0E;AAC1E,yEAAyE;AAyBzE,4DAA4D;AAC5D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE1D,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,MAAM,KAAK,GAAG,GAAG;SACd,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,IAAI,EAAE;SACN,WAAW,EAAE,CAAC;IACjB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,SAAgC;IAC/D,MAAM,GAAG,GAAqB,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACxE,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IACnC,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QACrC,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QACvC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC9B,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG;YACX,GAAG,EAAE,KAAK,CAAC,IAAI;YACf,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;YAC3B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB,CAAC;QACF,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,QAAQ;gBACX,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC3C,MAAM;YACR,KAAK,QAAQ;gBACX,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC7C,MAAM;YACR,KAAK,SAAS;gBACZ,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC7C,MAAM;YACR,KAAK,UAAU;gBACb,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC5E,MAAM;YACR;gBACE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC3C,GAAG,CAAC,QAAQ,CAAC,IAAI,CACf,UAAU,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,QAAQ,8GAA8G,CACxJ,CAAC;QACN,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RenderDomNode } from '@mapples/sid-ast';
|
|
2
|
+
/** Where `Styler` comes from in app code. */
|
|
3
|
+
export declare const STYLE_MODULE = "@mapples/style";
|
|
4
|
+
export interface HoistedStyles {
|
|
5
|
+
dictName: string;
|
|
6
|
+
/** Dictionary entries in document order: `[key, style object]`. */
|
|
7
|
+
entries: [string, unknown][];
|
|
8
|
+
/** The expression a node's `styled` key prints as, or undefined to print the literal. */
|
|
9
|
+
refFor: (node: RenderDomNode, key: string, value: unknown) => string | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare function hoistStyles(root: RenderDomNode, dictName?: string): HoistedStyles;
|
package/dist/styles.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// Hoisting generated styles: every object under a node's `styled` becomes an
|
|
2
|
+
// entry of one `const styles = Styler.create({…})` dictionary at the bottom
|
|
3
|
+
// of the file, and the tag reads `styled={{ style: styles.signInText }}`.
|
|
4
|
+
// Keys come from what the element shows (its text, label, placeholder…) and
|
|
5
|
+
// what it is, so a developer can find a style by reading the JSX.
|
|
6
|
+
/** Where `Styler` comes from in app code. */
|
|
7
|
+
export const STYLE_MODULE = '@mapples/style';
|
|
8
|
+
/** `styled` keys that hold a style object, and the word appended to the entry key for each. */
|
|
9
|
+
const STYLED_SUFFIX = {
|
|
10
|
+
style: '',
|
|
11
|
+
styleImage: 'Picture',
|
|
12
|
+
styleTypography: 'Label',
|
|
13
|
+
styleSvg: 'Glyph',
|
|
14
|
+
contentContainerStyle: 'Content',
|
|
15
|
+
};
|
|
16
|
+
/** The word for a node type inside an entry key. */
|
|
17
|
+
const TYPE_WORD = {
|
|
18
|
+
View: 'view',
|
|
19
|
+
SafeAreaView: 'screen',
|
|
20
|
+
ScrollView: 'scroll',
|
|
21
|
+
FlatList: 'list',
|
|
22
|
+
FormView: 'form',
|
|
23
|
+
Text: 'text',
|
|
24
|
+
Image: 'image',
|
|
25
|
+
Button: 'button',
|
|
26
|
+
SubmitButton: 'button',
|
|
27
|
+
TextInput: 'input',
|
|
28
|
+
TextField: 'input',
|
|
29
|
+
Vector: 'icon',
|
|
30
|
+
Icon: 'icon',
|
|
31
|
+
Custom: 'custom',
|
|
32
|
+
};
|
|
33
|
+
/** Props whose text names an element well enough to name its style. */
|
|
34
|
+
const HINT_PROPS = ['text', 'label', 'placeholder', 'title', 'alt', 'fieldName'];
|
|
35
|
+
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
36
|
+
/**
|
|
37
|
+
* "Please enter username and password" -> "pleaseEnterUsername". Words are
|
|
38
|
+
* letters only — a price like "0.99$" names nothing — and the result is a
|
|
39
|
+
* valid identifier start or empty.
|
|
40
|
+
*/
|
|
41
|
+
function hintWords(text) {
|
|
42
|
+
const words = text
|
|
43
|
+
.replace(/[^A-Za-z ]+/g, ' ')
|
|
44
|
+
.split(/\s+/)
|
|
45
|
+
.filter(Boolean)
|
|
46
|
+
.slice(0, 3)
|
|
47
|
+
.map((w) => w.toLowerCase());
|
|
48
|
+
if (words.length === 0)
|
|
49
|
+
return '';
|
|
50
|
+
return words[0] + words.slice(1).map(capitalize).join('');
|
|
51
|
+
}
|
|
52
|
+
function typeWord(node) {
|
|
53
|
+
if (node.type === 'Custom') {
|
|
54
|
+
const name = node.props.name;
|
|
55
|
+
return typeof name === 'string' && name !== ''
|
|
56
|
+
? name.charAt(0).toLowerCase() + name.slice(1)
|
|
57
|
+
: 'custom';
|
|
58
|
+
}
|
|
59
|
+
return TYPE_WORD[node.type] ?? node.type.charAt(0).toLowerCase() + node.type.slice(1);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The words an element's style keys are built from: `stem` is what it shows
|
|
63
|
+
* (`signIn`, `companyLogo`) or what it is when it shows nothing (`view`);
|
|
64
|
+
* `style` adds the type to a shown stem (`signInText`), the other `styled`
|
|
65
|
+
* keys add their own word to the stem (`signInLabel`, `companyLogoPicture`).
|
|
66
|
+
*/
|
|
67
|
+
function keyWords(node, isRoot) {
|
|
68
|
+
if (isRoot)
|
|
69
|
+
return { stem: 'root', style: 'root' };
|
|
70
|
+
const props = node.type === 'Custom' ? (node.props.layout ?? {}) : node.props;
|
|
71
|
+
const type = typeWord(node);
|
|
72
|
+
for (const prop of HINT_PROPS) {
|
|
73
|
+
const v = props[prop];
|
|
74
|
+
if (typeof v === 'string' && v.trim() !== '') {
|
|
75
|
+
const hint = hintWords(v);
|
|
76
|
+
if (hint !== '')
|
|
77
|
+
return { stem: hint, style: `${hint}${capitalize(type)}` };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return { stem: type, style: type };
|
|
81
|
+
}
|
|
82
|
+
function styledOf(node) {
|
|
83
|
+
const styled = node.type === 'Custom'
|
|
84
|
+
? (node.props.layout ?? {}).styled
|
|
85
|
+
: node.props.styled;
|
|
86
|
+
return typeof styled === 'object' && styled !== null && !Array.isArray(styled)
|
|
87
|
+
? styled
|
|
88
|
+
: null;
|
|
89
|
+
}
|
|
90
|
+
export function hoistStyles(root, dictName = 'styles') {
|
|
91
|
+
const entries = [];
|
|
92
|
+
const taken = new Set();
|
|
93
|
+
const refs = new Map(); // `${sid}|${styledKey}` -> entry key
|
|
94
|
+
const unique = (key) => {
|
|
95
|
+
let candidate = key;
|
|
96
|
+
for (let n = 2; taken.has(candidate); n += 1)
|
|
97
|
+
candidate = `${key}${n}`;
|
|
98
|
+
taken.add(candidate);
|
|
99
|
+
return candidate;
|
|
100
|
+
};
|
|
101
|
+
const visit = (node, isRoot) => {
|
|
102
|
+
const styled = styledOf(node);
|
|
103
|
+
if (styled) {
|
|
104
|
+
const words = keyWords(node, isRoot);
|
|
105
|
+
for (const [styledKey, value] of Object.entries(styled)) {
|
|
106
|
+
if (!(styledKey in STYLED_SUFFIX))
|
|
107
|
+
continue;
|
|
108
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
109
|
+
continue;
|
|
110
|
+
if (Object.keys(value).length === 0)
|
|
111
|
+
continue;
|
|
112
|
+
const suffix = STYLED_SUFFIX[styledKey];
|
|
113
|
+
const key = unique(suffix === '' ? words.style : `${words.stem}${suffix}`);
|
|
114
|
+
entries.push([key, value]);
|
|
115
|
+
refs.set(`${node.sid}|${styledKey}`, key);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
for (const child of node.children)
|
|
119
|
+
visit(child, false);
|
|
120
|
+
};
|
|
121
|
+
visit(root, true);
|
|
122
|
+
return {
|
|
123
|
+
dictName,
|
|
124
|
+
entries,
|
|
125
|
+
refFor: (node, key) => {
|
|
126
|
+
const entry = refs.get(`${node.sid}|${key}`);
|
|
127
|
+
return entry === undefined ? undefined : `${dictName}.${entry}`;
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mapples/codegen",
|
|
3
|
+
"version": "0.2.0-beta.2",
|
|
4
|
+
"description": "Pure RenderDom -> TSX file generation for Mapples pages and components: imports, hoisted styles, linked component instances. No I/O, no formatting.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Oleksandr Soloviov <oleksolv@gmail.com>",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc -b",
|
|
16
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@mapples/sid-ast": "^0.2.0-beta.2"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18.18"
|
|
23
|
+
}
|
|
24
|
+
}
|