mapples 0.2.0-beta.0 → 0.2.0-beta.3
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 +70 -22
- package/dist/adopt/scan.d.ts +8 -2
- package/dist/adopt/scan.js +31 -13
- package/dist/adopt/scan.js.map +1 -1
- package/dist/api/auth.d.ts +2 -0
- package/dist/api/auth.js +28 -6
- package/dist/api/auth.js.map +1 -1
- package/dist/api/client.d.ts +10 -1
- package/dist/api/client.js +24 -4
- package/dist/api/client.js.map +1 -1
- package/dist/api/commit.d.ts +9 -0
- package/dist/api/commit.js +35 -0
- package/dist/api/commit.js.map +1 -1
- package/dist/api/errors.js +8 -0
- package/dist/api/errors.js.map +1 -1
- package/dist/api/objects.d.ts +22 -5
- package/dist/api/objects.js +151 -10
- package/dist/api/objects.js.map +1 -1
- package/dist/api/poll.d.ts +5 -3
- package/dist/api/poll.js +17 -6
- package/dist/api/poll.js.map +1 -1
- package/dist/assets/assets.d.ts +9 -0
- package/dist/assets/assets.js +33 -4
- package/dist/assets/assets.js.map +1 -1
- package/dist/codegen/emit.d.ts +27 -1
- package/dist/codegen/emit.js +130 -9
- package/dist/codegen/emit.js.map +1 -1
- package/dist/codegen/imports.d.ts +2 -0
- package/dist/codegen/imports.js +38 -0
- package/dist/codegen/imports.js.map +1 -1
- package/dist/codegen/instances.d.ts +16 -0
- package/dist/codegen/instances.js +141 -0
- package/dist/codegen/instances.js.map +1 -0
- package/dist/codegen/styles.d.ts +11 -0
- package/dist/codegen/styles.js +131 -0
- package/dist/codegen/styles.js.map +1 -0
- package/dist/commands/impl/createImpl.js +8 -4
- package/dist/commands/impl/createImpl.js.map +1 -1
- package/dist/commands/impl/initImpl.js +5 -4
- package/dist/commands/impl/initImpl.js.map +1 -1
- package/dist/commands/impl/syncImpl.js +20 -2
- package/dist/commands/impl/syncImpl.js.map +1 -1
- package/dist/merge/applyOps.d.ts +1 -1
- package/dist/merge/applyOps.js +33 -2
- package/dist/merge/applyOps.js.map +1 -1
- package/dist/merge/diff.d.ts +1 -1
- package/dist/merge/diff.js +30 -17
- package/dist/merge/diff.js.map +1 -1
- package/dist/merge/threeWay.d.ts +1 -1
- package/dist/merge/threeWay.js +38 -6
- package/dist/merge/threeWay.js.map +1 -1
- package/dist/merge/toEdits.d.ts +1 -1
- package/dist/merge/toEdits.js +4 -1
- package/dist/merge/toEdits.js.map +1 -1
- package/dist/nav/navigatorTree.d.ts +78 -0
- package/dist/nav/navigatorTree.js +410 -0
- package/dist/nav/navigatorTree.js.map +1 -0
- package/dist/nav/placement.d.ts +53 -0
- package/dist/nav/placement.js +260 -0
- package/dist/nav/placement.js.map +1 -0
- package/dist/nav/routeTree.d.ts +8 -2
- package/dist/nav/routeTree.js +79 -151
- package/dist/nav/routeTree.js.map +1 -1
- package/dist/nav/screenOptions.d.ts +15 -0
- package/dist/nav/screenOptions.js +213 -0
- package/dist/nav/screenOptions.js.map +1 -0
- package/dist/project/baseStore.d.ts +8 -0
- package/dist/project/baseStore.js +15 -0
- package/dist/project/baseStore.js.map +1 -1
- package/dist/project/componentsMap.d.ts +7 -0
- package/dist/project/componentsMap.js +21 -0
- package/dist/project/componentsMap.js.map +1 -0
- package/dist/project/config.d.ts +12 -3
- package/dist/project/config.js +11 -2
- package/dist/project/config.js.map +1 -1
- package/dist/project/env.d.ts +10 -3
- package/dist/project/env.js +23 -5
- package/dist/project/env.js.map +1 -1
- package/dist/project/pagesMap.d.ts +2 -0
- package/dist/project/pagesMap.js.map +1 -1
- package/dist/services/adoptService.d.ts +3 -0
- package/dist/services/adoptService.js +346 -38
- package/dist/services/adoptService.js.map +1 -1
- package/dist/services/clientFactory.js +4 -2
- package/dist/services/clientFactory.js.map +1 -1
- package/dist/services/doctorService.js +77 -66
- package/dist/services/doctorService.js.map +1 -1
- package/dist/services/syncEngine.d.ts +7 -0
- package/dist/services/syncEngine.js +428 -292
- package/dist/services/syncEngine.js.map +1 -1
- package/dist/types.d.ts +21 -1
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/templates/app/_layout.tsx +3 -0
- package/templates/mapples/sid.d.ts +6 -0
package/dist/api/objects.js
CHANGED
|
@@ -1,24 +1,165 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
+
import { sidecarOf } from '../types.js';
|
|
3
|
+
// ---- Hash-linked blob resolution (RFC-0001 §4.1) ----
|
|
4
|
+
// The real backend embeds children as hash STRINGS, never inlined: a page blob
|
|
5
|
+
// is {id, name, root: "b3:…"} and a node blob is {id, key?, type, props,
|
|
6
|
+
// children: ["b3:…"], _canvasProps?}. The mock server may still serve
|
|
7
|
+
// materialized trees; both shapes resolve through the same walker.
|
|
8
|
+
const isHashRef = (v) => typeof v === 'string' && v.startsWith('b3:');
|
|
9
|
+
/** Editor-internal node fields that never enter the CLI's RenderDom model. */
|
|
10
|
+
const NODE_META_FIELDS = new Set([
|
|
11
|
+
'id',
|
|
12
|
+
'sid',
|
|
13
|
+
'key',
|
|
14
|
+
'type',
|
|
15
|
+
'props',
|
|
16
|
+
'children',
|
|
17
|
+
'refProps',
|
|
18
|
+
'dataProps',
|
|
19
|
+
'actionProps',
|
|
20
|
+
'_canvasProps',
|
|
21
|
+
'uuid',
|
|
22
|
+
]);
|
|
23
|
+
async function fetchObjects(client, hashes) {
|
|
24
|
+
const out = new Map();
|
|
25
|
+
for (let i = 0; i < hashes.length; i += 100) {
|
|
26
|
+
const chunk = hashes.slice(i, i + 100);
|
|
27
|
+
const objects = await client.objectsGet(chunk);
|
|
28
|
+
for (const h of chunk) {
|
|
29
|
+
if (!(h in objects))
|
|
30
|
+
throw new Error(`objects/get did not return blob ${h}`);
|
|
31
|
+
out.set(h, objects[h]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
/** Resolve a root ref (hash or inline tree) into a materialized RenderDomNode. */
|
|
37
|
+
async function materializeTree(client, rootRef) {
|
|
38
|
+
// Breadth-first: collect unresolved hashes level by level, batch-fetch them.
|
|
39
|
+
const blobCache = new Map();
|
|
40
|
+
const collectHashes = (ref, acc) => {
|
|
41
|
+
if (isHashRef(ref)) {
|
|
42
|
+
if (!blobCache.has(ref))
|
|
43
|
+
acc.add(ref);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const node = ref;
|
|
47
|
+
for (const child of node.children ?? [])
|
|
48
|
+
collectHashes(child, acc);
|
|
49
|
+
};
|
|
50
|
+
let frontier = [rootRef];
|
|
51
|
+
for (let depth = 0; depth < 100 && frontier.length > 0; depth++) {
|
|
52
|
+
const wanted = new Set();
|
|
53
|
+
for (const ref of frontier)
|
|
54
|
+
collectHashes(ref, wanted);
|
|
55
|
+
if (wanted.size === 0)
|
|
56
|
+
break;
|
|
57
|
+
const fetched = await fetchObjects(client, [...wanted]);
|
|
58
|
+
for (const [h, blob] of fetched)
|
|
59
|
+
blobCache.set(h, blob);
|
|
60
|
+
frontier = [...fetched.values()];
|
|
61
|
+
}
|
|
62
|
+
const build = (ref, trail) => {
|
|
63
|
+
let blob = ref;
|
|
64
|
+
if (isHashRef(ref)) {
|
|
65
|
+
if (trail.has(ref))
|
|
66
|
+
throw new Error(`cycle in canvas blobs at ${ref}`);
|
|
67
|
+
trail = new Set(trail).add(ref);
|
|
68
|
+
blob = blobCache.get(ref);
|
|
69
|
+
if (blob === undefined)
|
|
70
|
+
throw new Error(`unresolved canvas blob ${ref}`);
|
|
71
|
+
}
|
|
72
|
+
const node = blob;
|
|
73
|
+
const sid = (node.id ?? node.sid);
|
|
74
|
+
if (typeof sid !== 'string' || typeof node.type !== 'string') {
|
|
75
|
+
throw new Error(`canvas node blob is missing id/type: ${JSON.stringify(node).slice(0, 120)}`);
|
|
76
|
+
}
|
|
77
|
+
// Anything beyond the known meta fields is unexpected — keep it visible.
|
|
78
|
+
for (const k of Object.keys(node)) {
|
|
79
|
+
if (!NODE_META_FIELDS.has(k)) {
|
|
80
|
+
throw new Error(`canvas node ${sid} has unknown field \`${k}\` — schema drift, update the CLI`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
sid,
|
|
85
|
+
type: node.type,
|
|
86
|
+
props: node.props ?? {},
|
|
87
|
+
children: (node.children ?? []).map((c) => build(c, trail)),
|
|
88
|
+
...sidecarOf(node),
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
return build(rootRef, new Set());
|
|
92
|
+
}
|
|
93
|
+
/** Pages on the real backend carry no route; derive a stable one from the name. */
|
|
94
|
+
export function deriveRoute(name) {
|
|
95
|
+
const slug = name
|
|
96
|
+
.trim()
|
|
97
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
98
|
+
.replace(/[^A-Za-z0-9]+/g, '-')
|
|
99
|
+
.replace(/^-+|-+$/g, '')
|
|
100
|
+
.toLowerCase();
|
|
101
|
+
return slug === '' || slug === 'home' || slug === 'index' ? '/' : `/${slug}`;
|
|
102
|
+
}
|
|
103
|
+
/** A style-blob section may be inline, hash-linked, or a {id, data} document. */
|
|
104
|
+
async function resolveStyleSection(client, value) {
|
|
105
|
+
let section = value;
|
|
106
|
+
if (isHashRef(section)) {
|
|
107
|
+
const fetched = await fetchObjects(client, [section]);
|
|
108
|
+
section = fetched.get(section);
|
|
109
|
+
}
|
|
110
|
+
if (typeof section !== 'object' || section === null)
|
|
111
|
+
return {};
|
|
112
|
+
const doc = section;
|
|
113
|
+
if (typeof doc.data === 'object' && doc.data !== null)
|
|
114
|
+
return doc.data;
|
|
115
|
+
return doc;
|
|
116
|
+
}
|
|
2
117
|
/** Cold bootstrap: walk the manifest and fetch every blob (RFC-0001 §6). */
|
|
3
118
|
export async function fetchProjectState(client, boot) {
|
|
4
|
-
const [pagesIndex, componentsIndex,
|
|
119
|
+
const [pagesIndex, componentsIndex, navigationBlob, styleBlob, assets] = await Promise.all([
|
|
5
120
|
client.getObject(boot.manifest.pages),
|
|
6
121
|
client.getObject(boot.manifest.components),
|
|
7
122
|
client.getObject(boot.manifest.navigation),
|
|
8
123
|
client.getObject(boot.manifest.style),
|
|
9
124
|
client.getObject(boot.manifest.assets),
|
|
10
125
|
]);
|
|
126
|
+
const pageBlobs = await fetchObjects(client, Object.values(pagesIndex));
|
|
11
127
|
const pages = new Map();
|
|
12
|
-
|
|
13
|
-
const blob =
|
|
14
|
-
pages.set(
|
|
15
|
-
|
|
128
|
+
for (const [indexId, hash] of Object.entries(pagesIndex)) {
|
|
129
|
+
const blob = pageBlobs.get(hash);
|
|
130
|
+
pages.set(indexId, {
|
|
131
|
+
id: blob.id ?? indexId,
|
|
132
|
+
name: blob.name,
|
|
133
|
+
route: blob.route ?? deriveRoute(blob.name),
|
|
134
|
+
root: await materializeTree(client, blob.root),
|
|
135
|
+
...(blob.uuid ? { uuid: blob.uuid } : {}),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const componentBlobs = await fetchObjects(client, Object.values(componentsIndex));
|
|
16
139
|
const components = new Map();
|
|
17
|
-
|
|
18
|
-
const blob =
|
|
19
|
-
components.set(
|
|
20
|
-
|
|
21
|
-
|
|
140
|
+
for (const [indexId, hash] of Object.entries(componentsIndex)) {
|
|
141
|
+
const blob = componentBlobs.get(hash);
|
|
142
|
+
components.set(indexId, {
|
|
143
|
+
id: blob.id ?? indexId,
|
|
144
|
+
name: blob.name,
|
|
145
|
+
root: await materializeTree(client, blob.root),
|
|
146
|
+
...(blob.uuid ? { uuid: blob.uuid } : {}),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
const style = {
|
|
150
|
+
theme: await resolveStyleSection(client, styleBlob.theme),
|
|
151
|
+
typography: await resolveStyleSection(client, styleBlob.typography),
|
|
152
|
+
sizing: await resolveStyleSection(client, styleBlob.sizing),
|
|
153
|
+
};
|
|
154
|
+
return {
|
|
155
|
+
head: boot.head,
|
|
156
|
+
seq: boot.seq,
|
|
157
|
+
pages,
|
|
158
|
+
components,
|
|
159
|
+
navigation: navigationBlob,
|
|
160
|
+
style,
|
|
161
|
+
assets,
|
|
162
|
+
};
|
|
22
163
|
}
|
|
23
164
|
/**
|
|
24
165
|
* Upload binary asset bodies: `objects/have` filters to genuinely missing
|
package/dist/api/objects.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objects.js","sourceRoot":"","sources":["../../src/api/objects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"objects.js","sourceRoot":"","sources":["../../src/api/objects.ts"],"names":[],"mappings":"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"}
|
package/dist/api/poll.d.ts
CHANGED
|
@@ -4,7 +4,9 @@ export declare class SnapshotRequired extends Error {
|
|
|
4
4
|
constructor();
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
|
-
* Pull the full delta since `
|
|
8
|
-
*
|
|
7
|
+
* Pull the full delta since `sinceSeq`, following `truncated: true` pages via
|
|
8
|
+
* `lastSeq` until exhausted. The real backend signals "cold-bootstrap instead"
|
|
9
|
+
* with a 200 `snapshotRequired: true` body; older servers/mocks may use a
|
|
10
|
+
* SNAPSHOT_REQUIRED error — both raise SnapshotRequired.
|
|
9
11
|
*/
|
|
10
|
-
export declare function pullDelta(client: JpatchClient,
|
|
12
|
+
export declare function pullDelta(client: JpatchClient, sinceSeq: number): Promise<Delta>;
|
package/dist/api/poll.js
CHANGED
|
@@ -6,13 +6,15 @@ export class SnapshotRequired extends Error {
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* Pull the full delta since `
|
|
10
|
-
*
|
|
9
|
+
* Pull the full delta since `sinceSeq`, following `truncated: true` pages via
|
|
10
|
+
* `lastSeq` until exhausted. The real backend signals "cold-bootstrap instead"
|
|
11
|
+
* with a 200 `snapshotRequired: true` body; older servers/mocks may use a
|
|
12
|
+
* SNAPSHOT_REQUIRED error — both raise SnapshotRequired.
|
|
11
13
|
*/
|
|
12
|
-
export async function pullDelta(client,
|
|
14
|
+
export async function pullDelta(client, sinceSeq) {
|
|
13
15
|
const ops = [];
|
|
14
|
-
let cursor =
|
|
15
|
-
for (
|
|
16
|
+
let cursor = sinceSeq;
|
|
17
|
+
for (let page_n = 0; page_n < 1000; page_n++) {
|
|
16
18
|
let page;
|
|
17
19
|
try {
|
|
18
20
|
page = await client.pullOnce(cursor);
|
|
@@ -23,11 +25,20 @@ export async function pullDelta(client, since) {
|
|
|
23
25
|
}
|
|
24
26
|
throw err;
|
|
25
27
|
}
|
|
28
|
+
if (page.snapshotRequired)
|
|
29
|
+
throw new SnapshotRequired();
|
|
30
|
+
if (!Array.isArray(page.ops)) {
|
|
31
|
+
throw new Error(`delta response has no ops array (head ${page.head}) — server/CLI contract drift`);
|
|
32
|
+
}
|
|
26
33
|
ops.push(...page.ops);
|
|
27
34
|
if (!page.truncated) {
|
|
28
35
|
return { ops, head: page.head, seq: page.seq, truncated: false };
|
|
29
36
|
}
|
|
30
|
-
|
|
37
|
+
if (typeof page.lastSeq !== 'number' || page.lastSeq <= cursor) {
|
|
38
|
+
throw new Error('truncated delta without an advancing lastSeq cursor');
|
|
39
|
+
}
|
|
40
|
+
cursor = page.lastSeq;
|
|
31
41
|
}
|
|
42
|
+
throw new Error('delta paging did not converge after 1000 pages');
|
|
32
43
|
}
|
|
33
44
|
//# sourceMappingURL=poll.js.map
|
package/dist/api/poll.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/api/poll.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC;QACE,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAC7E,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED
|
|
1
|
+
{"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/api/poll.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC;QACE,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAC7E,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAoB,EAAE,QAAgB;IACpE,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,IAAI,MAAM,GAAG,QAAQ,CAAC;IACtB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;QAC7C,IAAI,IAAW,CAAC;QAChB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,WAAW,IAAI,GAAG,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;gBACnE,MAAM,IAAI,gBAAgB,EAAE,CAAC;YAC/B,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,IAAI,IAAI,CAAC,gBAAgB;YAAE,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACxD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,yCAAyC,IAAI,CAAC,IAAI,+BAA+B,CAClF,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QACnE,CAAC;QACD,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;AACpE,CAAC"}
|
package/dist/assets/assets.d.ts
CHANGED
|
@@ -4,6 +4,15 @@ import type { JpatchOp } from '../types.js';
|
|
|
4
4
|
import type { SyncReport } from '../ui/report.js';
|
|
5
5
|
export declare const ASSETS_DIR: string;
|
|
6
6
|
export declare const ASSET_MAP_FILE: string;
|
|
7
|
+
/** A filesystem-safe local name for an asset record (real records may carry
|
|
8
|
+
* display names like "placeholder: Onboarding hero — teamwork"). */
|
|
9
|
+
export declare function assetFileName(id: string, meta: {
|
|
10
|
+
name?: string;
|
|
11
|
+
file_name?: string;
|
|
12
|
+
extension?: string;
|
|
13
|
+
mime?: string;
|
|
14
|
+
type?: string;
|
|
15
|
+
}): string;
|
|
7
16
|
export interface AssetSyncResult {
|
|
8
17
|
pushOps: JpatchOp[];
|
|
9
18
|
mergedAssets: AssetIndex;
|
package/dist/assets/assets.js
CHANGED
|
@@ -21,19 +21,48 @@ const MIME_BY_EXT = {
|
|
|
21
21
|
'.json': 'application/json',
|
|
22
22
|
};
|
|
23
23
|
const EXT_BY_MIME = Object.fromEntries(Object.entries(MIME_BY_EXT).map(([ext, mime]) => [mime, ext]));
|
|
24
|
+
/** A filesystem-safe local name for an asset record (real records may carry
|
|
25
|
+
* display names like "placeholder: Onboarding hero — teamwork"). */
|
|
26
|
+
export function assetFileName(id, meta) {
|
|
27
|
+
const rawBase = meta.file_name || meta.name || id;
|
|
28
|
+
const base = rawBase
|
|
29
|
+
.replace(/[/\\:*?"<>|]/g, '-')
|
|
30
|
+
.replace(/\s+/g, ' ')
|
|
31
|
+
.trim()
|
|
32
|
+
.slice(0, 120);
|
|
33
|
+
const hasExt = /\.[A-Za-z0-9]{1,5}$/.test(base);
|
|
34
|
+
if (hasExt)
|
|
35
|
+
return base;
|
|
36
|
+
const ext = (meta.extension ? `.${meta.extension.replace(/^\./, '')}` : '') ||
|
|
37
|
+
(meta.mime ? (EXT_BY_MIME[meta.mime] ?? '') : '') ||
|
|
38
|
+
(meta.type === 'image' ? '.png' : '');
|
|
39
|
+
return `${base}${ext}`;
|
|
40
|
+
}
|
|
24
41
|
export async function syncAssets(root, client, remote, report) {
|
|
25
42
|
const dir = join(root, ASSETS_DIR);
|
|
26
43
|
const index = structuredClone(remote ?? {});
|
|
27
44
|
const pushOps = [];
|
|
28
45
|
const knownShas = new Set(Object.values(index).map((a) => a.sha256));
|
|
29
46
|
const namesInIndex = new Map(Object.entries(index).map(([id, a]) => [a.name ?? id, id]));
|
|
30
|
-
// 1. Pull: remote assets not on disk get downloaded.
|
|
47
|
+
// 1. Pull: remote assets not on disk get downloaded. Real records (dev
|
|
48
|
+
// backend) carry a server-relative `link`; the mock's carry sha256+mime
|
|
49
|
+
// served via canvas objects.
|
|
31
50
|
for (const [id, meta] of Object.entries(index)) {
|
|
32
|
-
const fileName =
|
|
51
|
+
const fileName = assetFileName(id, meta);
|
|
33
52
|
const filePath = join(dir, fileName);
|
|
34
53
|
if (existsSync(filePath))
|
|
35
54
|
continue;
|
|
36
|
-
|
|
55
|
+
let bytes;
|
|
56
|
+
if (typeof meta.link === 'string' && meta.link.length > 0) {
|
|
57
|
+
bytes = await client.getBytesAtPath(meta.link);
|
|
58
|
+
}
|
|
59
|
+
else if (meta.sha256) {
|
|
60
|
+
bytes = await client.getObjectBytes(`sha256:${meta.sha256}`);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
report.notes.push(`asset ${id} has neither link nor sha256 — skipped`);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
37
66
|
mkdirSync(dir, { recursive: true });
|
|
38
67
|
writeFileSync(filePath, bytes);
|
|
39
68
|
report.files.push({ file: join(ASSETS_DIR, fileName), action: 'created' });
|
|
@@ -82,7 +111,7 @@ export function writeAssetMap(root, index, report) {
|
|
|
82
111
|
return;
|
|
83
112
|
const lines = Object.entries(index)
|
|
84
113
|
.sort(([a], [b]) => (a < b ? -1 : 1))
|
|
85
|
-
.map(([id, meta]) => ` '${id}': require('./assets/${meta
|
|
114
|
+
.map(([id, meta]) => ` '${id}': require('./assets/${assetFileName(id, meta)}'),`);
|
|
86
115
|
const content = [
|
|
87
116
|
'// GENERATED by Mapples — DO NOT EDIT. Regenerated on every `mapples sync`.',
|
|
88
117
|
'/* eslint-disable @typescript-eslint/no-require-imports */',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/assets/assets.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,8EAA8E;AAC9E,gDAAgD;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAI1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAI3C,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AACpD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AAE7D,MAAM,WAAW,GAA2B;IAC1C,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,kBAAkB;CAC5B,CAAC;AAEF,MAAM,WAAW,GAA2B,MAAM,CAAC,WAAW,CAC5D,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAC9D,CAAC;
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/assets/assets.ts"],"names":[],"mappings":"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"}
|
package/dist/codegen/emit.d.ts
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
import type { RenderDomNode } from '../types.js';
|
|
2
2
|
export declare const GENERATED_HEADER: string;
|
|
3
|
-
|
|
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;
|
|
4
18
|
export interface EmitPageInput {
|
|
5
19
|
name: string;
|
|
6
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
|
+
};
|
|
7
26
|
}
|
|
8
27
|
export declare function emitPage(page: EmitPageInput, filePath?: string): Promise<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, filePath?: string): Promise<string>;
|
package/dist/codegen/emit.js
CHANGED
|
@@ -1,31 +1,152 @@
|
|
|
1
|
-
// RenderDom page -> complete
|
|
1
|
+
// RenderDom page -> complete page file. Deterministic: stable prop order
|
|
2
2
|
// (sid-ast printer), stable import order, Prettier-formatted.
|
|
3
|
-
|
|
3
|
+
//
|
|
4
|
+
// A page file lives where expo-router expects the route (RFC-0002 §5 file
|
|
5
|
+
// layout): `app/<segment>.tsx` for a routed page, `<pagesDir>/<Name>.tsx` for
|
|
6
|
+
// a page that is not in the navigation yet. Routed files open with a route
|
|
7
|
+
// marker line that carries the route id — the file's identity for renames.
|
|
8
|
+
import { printNode, printValue } from '@mapples/sid-ast';
|
|
4
9
|
import { collectImports, printImports } from './imports.js';
|
|
5
10
|
import { formatTsx } from './format.js';
|
|
11
|
+
import { hoistStyles, STYLE_MODULE } from './styles.js';
|
|
6
12
|
export const GENERATED_HEADER = '// Generated by Mapples — edit freely, but keep the $sid props intact.\n' +
|
|
7
13
|
'// Two-way sync: `mapples sync` reconciles this file with Mapples Creator.';
|
|
8
|
-
|
|
9
|
-
|
|
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
|
|
10
103
|
.split(/[^A-Za-z0-9]+/)
|
|
11
104
|
.filter(Boolean)
|
|
12
105
|
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
13
106
|
.join('');
|
|
14
|
-
|
|
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;
|
|
15
113
|
}
|
|
16
114
|
export async function emitPage(page, filePath) {
|
|
17
|
-
|
|
18
|
-
|
|
115
|
+
return emitTree(page.name, page.root, page.route ? [routeMarkerLine(page.route.id, page.route.name)] : [], filePath);
|
|
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 async function emitComponent(component, filePath) {
|
|
121
|
+
return emitTree(component.name, component.root, [], filePath, COMPONENT_HEADER, 'Component');
|
|
122
|
+
}
|
|
123
|
+
async function emitTree(name, root, leading, filePath, 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);
|
|
19
130
|
const code = [
|
|
20
|
-
|
|
131
|
+
...leading,
|
|
132
|
+
header,
|
|
21
133
|
'',
|
|
22
134
|
printImports(imports),
|
|
135
|
+
...(styles.entries.length > 0 ? [`import { Styler } from '${STYLE_MODULE}';`] : []),
|
|
23
136
|
'',
|
|
24
|
-
`export default function ${
|
|
137
|
+
`export default function ${componentName}() {`,
|
|
25
138
|
' return (',
|
|
26
139
|
jsx,
|
|
27
140
|
' );',
|
|
28
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
|
+
: []),
|
|
29
150
|
'',
|
|
30
151
|
].join('\n');
|
|
31
152
|
return formatTsx(code, filePath);
|
package/dist/codegen/emit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/codegen/emit.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/codegen/emit.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,3 +13,5 @@ export declare function parseImportRef(ref: string): {
|
|
|
13
13
|
};
|
|
14
14
|
export declare function collectImports(root: RenderDomNode): ResolvedImports;
|
|
15
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: import('../types.js').RenderDomNode): import('@mapples/sid-ast').ImportNeed[];
|
package/dist/codegen/imports.js
CHANGED
|
@@ -76,4 +76,42 @@ export function printImports(resolved) {
|
|
|
76
76
|
}
|
|
77
77
|
return lines.join('\n');
|
|
78
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
|
+
}
|
|
79
117
|
//# sourceMappingURL=imports.js.map
|