mapples 0.1.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.
Files changed (135) hide show
  1. package/README.md +42 -0
  2. package/dist/adopt/mappingTable.d.ts +1 -0
  3. package/dist/adopt/mappingTable.js +18 -0
  4. package/dist/adopt/mappingTable.js.map +1 -0
  5. package/dist/adopt/scan.d.ts +4 -0
  6. package/dist/adopt/scan.js +51 -0
  7. package/dist/adopt/scan.js.map +1 -0
  8. package/dist/api/canonical.d.ts +12 -0
  9. package/dist/api/canonical.js +65 -0
  10. package/dist/api/canonical.js.map +1 -0
  11. package/dist/api/client.d.ts +37 -0
  12. package/dist/api/client.js +79 -0
  13. package/dist/api/client.js.map +1 -0
  14. package/dist/api/commit.d.ts +18 -0
  15. package/dist/api/commit.js +47 -0
  16. package/dist/api/commit.js.map +1 -0
  17. package/dist/api/errors.d.ts +30 -0
  18. package/dist/api/errors.js +74 -0
  19. package/dist/api/errors.js.map +1 -0
  20. package/dist/api/objects.d.ts +55 -0
  21. package/dist/api/objects.js +48 -0
  22. package/dist/api/objects.js.map +1 -0
  23. package/dist/api/poll.d.ts +10 -0
  24. package/dist/api/poll.js +33 -0
  25. package/dist/api/poll.js.map +1 -0
  26. package/dist/assets/assets.d.ts +15 -0
  27. package/dist/assets/assets.js +110 -0
  28. package/dist/assets/assets.js.map +1 -0
  29. package/dist/codegen/emit.d.ts +8 -0
  30. package/dist/codegen/emit.js +33 -0
  31. package/dist/codegen/emit.js.map +1 -0
  32. package/dist/codegen/format.d.ts +8 -0
  33. package/dist/codegen/format.js +24 -0
  34. package/dist/codegen/format.js.map +1 -0
  35. package/dist/codegen/imports.d.ts +15 -0
  36. package/dist/codegen/imports.js +79 -0
  37. package/dist/codegen/imports.js.map +1 -0
  38. package/dist/commands/adopt.d.ts +2 -0
  39. package/dist/commands/adopt.js +11 -0
  40. package/dist/commands/adopt.js.map +1 -0
  41. package/dist/commands/create.d.ts +2 -0
  42. package/dist/commands/create.js +13 -0
  43. package/dist/commands/create.js.map +1 -0
  44. package/dist/commands/doctor.d.ts +2 -0
  45. package/dist/commands/doctor.js +11 -0
  46. package/dist/commands/doctor.js.map +1 -0
  47. package/dist/commands/impl/adoptImpl.d.ts +1 -0
  48. package/dist/commands/impl/adoptImpl.js +24 -0
  49. package/dist/commands/impl/adoptImpl.js.map +1 -0
  50. package/dist/commands/impl/createImpl.d.ts +2 -0
  51. package/dist/commands/impl/createImpl.js +65 -0
  52. package/dist/commands/impl/createImpl.js.map +1 -0
  53. package/dist/commands/impl/doctorImpl.d.ts +1 -0
  54. package/dist/commands/impl/doctorImpl.js +25 -0
  55. package/dist/commands/impl/doctorImpl.js.map +1 -0
  56. package/dist/commands/impl/initImpl.d.ts +1 -0
  57. package/dist/commands/impl/initImpl.js +65 -0
  58. package/dist/commands/impl/initImpl.js.map +1 -0
  59. package/dist/commands/impl/syncImpl.d.ts +1 -0
  60. package/dist/commands/impl/syncImpl.js +34 -0
  61. package/dist/commands/impl/syncImpl.js.map +1 -0
  62. package/dist/commands/init.d.ts +2 -0
  63. package/dist/commands/init.js +13 -0
  64. package/dist/commands/init.js.map +1 -0
  65. package/dist/commands/sync.d.ts +2 -0
  66. package/dist/commands/sync.js +13 -0
  67. package/dist/commands/sync.js.map +1 -0
  68. package/dist/index.d.ts +2 -0
  69. package/dist/index.js +23 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/merge/applyOps.d.ts +11 -0
  72. package/dist/merge/applyOps.js +134 -0
  73. package/dist/merge/applyOps.js.map +1 -0
  74. package/dist/merge/deprecate.d.ts +3 -0
  75. package/dist/merge/deprecate.js +28 -0
  76. package/dist/merge/deprecate.js.map +1 -0
  77. package/dist/merge/diff.d.ts +15 -0
  78. package/dist/merge/diff.js +124 -0
  79. package/dist/merge/diff.js.map +1 -0
  80. package/dist/merge/mergePatch.d.ts +8 -0
  81. package/dist/merge/mergePatch.js +63 -0
  82. package/dist/merge/mergePatch.js.map +1 -0
  83. package/dist/merge/threeWay.d.ts +15 -0
  84. package/dist/merge/threeWay.js +242 -0
  85. package/dist/merge/threeWay.js.map +1 -0
  86. package/dist/merge/toEdits.d.ts +3 -0
  87. package/dist/merge/toEdits.js +92 -0
  88. package/dist/merge/toEdits.js.map +1 -0
  89. package/dist/nav/routeTree.d.ts +11 -0
  90. package/dist/nav/routeTree.js +182 -0
  91. package/dist/nav/routeTree.js.map +1 -0
  92. package/dist/project/baseStore.d.ts +19 -0
  93. package/dist/project/baseStore.js +78 -0
  94. package/dist/project/baseStore.js.map +1 -0
  95. package/dist/project/config.d.ts +13 -0
  96. package/dist/project/config.js +28 -0
  97. package/dist/project/config.js.map +1 -0
  98. package/dist/project/head.d.ts +6 -0
  99. package/dist/project/head.js +22 -0
  100. package/dist/project/head.js.map +1 -0
  101. package/dist/project/outbox.d.ts +14 -0
  102. package/dist/project/outbox.js +31 -0
  103. package/dist/project/outbox.js.map +1 -0
  104. package/dist/project/pagesMap.d.ts +8 -0
  105. package/dist/project/pagesMap.js +20 -0
  106. package/dist/project/pagesMap.js.map +1 -0
  107. package/dist/services/adoptService.d.ts +11 -0
  108. package/dist/services/adoptService.js +197 -0
  109. package/dist/services/adoptService.js.map +1 -0
  110. package/dist/services/doctorService.d.ts +11 -0
  111. package/dist/services/doctorService.js +135 -0
  112. package/dist/services/doctorService.js.map +1 -0
  113. package/dist/services/scaffold.d.ts +7 -0
  114. package/dist/services/scaffold.js +56 -0
  115. package/dist/services/scaffold.js.map +1 -0
  116. package/dist/services/syncEngine.d.ts +11 -0
  117. package/dist/services/syncEngine.js +618 -0
  118. package/dist/services/syncEngine.js.map +1 -0
  119. package/dist/style/theme.d.ts +12 -0
  120. package/dist/style/theme.js +125 -0
  121. package/dist/style/theme.js.map +1 -0
  122. package/dist/types.d.ts +136 -0
  123. package/dist/types.js +6 -0
  124. package/dist/types.js.map +1 -0
  125. package/dist/ui/report.d.ts +24 -0
  126. package/dist/ui/report.js +50 -0
  127. package/dist/ui/report.js.map +1 -0
  128. package/package.json +38 -0
  129. package/templates/app/_layout.tsx +5 -0
  130. package/templates/app.json +15 -0
  131. package/templates/babel.config.js +8 -0
  132. package/templates/gitignore +7 -0
  133. package/templates/mapples/sid.d.ts +13 -0
  134. package/templates/package.json +30 -0
  135. package/templates/tsconfig.json +10 -0
@@ -0,0 +1,242 @@
1
+ // The per-node 3-way merge — RFC-0002 §4, normative. Inputs per entity:
2
+ // base (.mapples/base), local (fresh extract), remote (base + pulled ops).
3
+ // Compared per $sid node, per prop key. Any conflict deprecates the whole file
4
+ // (the caller's job); this module only decides and merges.
5
+ import { deepEqual } from './mergePatch.js';
6
+ import { indexTree } from './diff.js';
7
+ function touchedProps(from, to) {
8
+ const touched = new Map();
9
+ if (from.type !== to.type)
10
+ touched.set('type', to.type);
11
+ for (const key of new Set([...Object.keys(from.props), ...Object.keys(to.props)])) {
12
+ if (!deepEqual(from.props[key], to.props[key])) {
13
+ touched.set(key, key in to.props ? to.props[key] : undefined); // undefined = deleted
14
+ }
15
+ }
16
+ return touched;
17
+ }
18
+ /** ids of `perm` not part of a longest common subsequence with `base` — the minimal moved set. */
19
+ function movedIds(base, perm) {
20
+ // LCS over the common ids.
21
+ const b = base.filter((id) => perm.includes(id));
22
+ const p = perm.filter((id) => b.includes(id));
23
+ const n = b.length;
24
+ const m = p.length;
25
+ const dp = Array.from({ length: n + 1 }, () => Array(m + 1).fill(0));
26
+ for (let i = n - 1; i >= 0; i--) {
27
+ for (let j = m - 1; j >= 0; j--) {
28
+ dp[i][j] = b[i] === p[j] ? dp[i + 1][j + 1] + 1 : Math.max(dp[i + 1][j], dp[i][j + 1]);
29
+ }
30
+ }
31
+ const inLcs = new Set();
32
+ let i = 0;
33
+ let j = 0;
34
+ while (i < n && j < m) {
35
+ if (b[i] === p[j]) {
36
+ inLcs.add(b[i]);
37
+ i++;
38
+ j++;
39
+ }
40
+ else if (dp[i + 1][j] >= dp[i][j + 1])
41
+ i++;
42
+ else
43
+ j++;
44
+ }
45
+ return new Set(p.filter((id) => !inLcs.has(id)));
46
+ }
47
+ function reposition(order, id, targetOrder) {
48
+ const from = order.indexOf(id);
49
+ if (from !== -1)
50
+ order.splice(from, 1);
51
+ // Place after the nearest preceding id (in targetOrder) that is already in `order`.
52
+ const tIdx = targetOrder.indexOf(id);
53
+ let anchor = -1;
54
+ for (let k = tIdx - 1; k >= 0; k--) {
55
+ const prev = targetOrder[k];
56
+ const at = order.indexOf(prev);
57
+ if (at !== -1) {
58
+ anchor = at;
59
+ break;
60
+ }
61
+ }
62
+ order.splice(anchor + 1, 0, id);
63
+ }
64
+ export function threeWayMerge(base, local, remote) {
65
+ const bIdx = indexTree(base);
66
+ const lIdx = indexTree(local);
67
+ const rIdx = indexTree(remote);
68
+ const conflicts = [];
69
+ // ---- presence in merged, per sid ----
70
+ const present = new Set();
71
+ const union = new Set([...bIdx.keys(), ...lIdx.keys(), ...rIdx.keys()]);
72
+ for (const sid of union) {
73
+ const inB = bIdx.has(sid);
74
+ const inL = lIdx.has(sid);
75
+ const inR = rIdx.has(sid);
76
+ if (!inB) {
77
+ // Created on one side (same sid can't be minted on both).
78
+ present.add(sid);
79
+ continue;
80
+ }
81
+ const deletedL = !inL;
82
+ const deletedR = !inR;
83
+ if (deletedL && deletedR)
84
+ continue; // both agree: gone
85
+ if (deletedL) {
86
+ const rTouched = touchedProps(bIdx.get(sid).node, rIdx.get(sid).node);
87
+ if (rTouched.size > 0) {
88
+ conflicts.push({
89
+ sid,
90
+ reason: 'delete-vs-edit',
91
+ props: [...rTouched.keys()],
92
+ detail: `deleted locally but edited in Creator (${[...rTouched.keys()].join(', ')})`,
93
+ });
94
+ present.add(sid); // remote wins inside a deprecated file
95
+ }
96
+ // else: clean local delete — absent from merged, push carries the delete
97
+ continue;
98
+ }
99
+ if (deletedR) {
100
+ const lTouched = touchedProps(bIdx.get(sid).node, lIdx.get(sid).node);
101
+ if (lTouched.size > 0) {
102
+ conflicts.push({
103
+ sid,
104
+ reason: 'delete-vs-edit',
105
+ props: [...lTouched.keys()],
106
+ detail: `deleted in Creator but edited locally (${[...lTouched.keys()].join(', ')})`,
107
+ });
108
+ // remote wins: absent from merged
109
+ }
110
+ continue;
111
+ }
112
+ present.add(sid);
113
+ }
114
+ // ---- per-sid merged shell (type + props) ----
115
+ const mergedShell = new Map();
116
+ for (const sid of present) {
117
+ const b = bIdx.get(sid)?.node;
118
+ const l = lIdx.get(sid)?.node;
119
+ const r = rIdx.get(sid)?.node;
120
+ if (!b) {
121
+ const source = l ?? r;
122
+ if (!source)
123
+ continue;
124
+ mergedShell.set(sid, { type: source.type, props: source.props });
125
+ continue;
126
+ }
127
+ const lNode = l ?? b; // deleted-but-conflicted nodes fall back to base/remote
128
+ const rNode = r ?? b;
129
+ const lTouched = touchedProps(b, lNode);
130
+ const rTouched = touchedProps(b, rNode);
131
+ const overlap = [...lTouched.keys()].filter((k) => rTouched.has(k) && !deepEqual(lTouched.get(k), rTouched.get(k)));
132
+ if (overlap.length > 0) {
133
+ conflicts.push({
134
+ sid,
135
+ reason: 'same-prop',
136
+ props: overlap,
137
+ localValue: lTouched.get(overlap[0]),
138
+ remoteValue: rTouched.get(overlap[0]),
139
+ detail: `both sides changed ${overlap.join(', ')}`,
140
+ });
141
+ }
142
+ // Merged props: base, then remote changes, then local changes (local wins
143
+ // on overlap here, but overlaps only survive into `merged` when the caller
144
+ // ignores conflicts — a conflicted file uses remote wholesale anyway).
145
+ let type = b.type;
146
+ const props = { ...b.props };
147
+ const apply = (touched) => {
148
+ for (const [key, value] of touched) {
149
+ if (key === 'type')
150
+ type = value;
151
+ else if (value === undefined)
152
+ delete props[key];
153
+ else
154
+ props[key] = value;
155
+ }
156
+ };
157
+ apply(rTouched);
158
+ apply(lTouched);
159
+ mergedShell.set(sid, { type, props });
160
+ }
161
+ // ---- children ordering per present parent ----
162
+ const mergedKids = new Map();
163
+ const kidsOf = (idx, sid) => {
164
+ const entry = idx.get(sid);
165
+ return entry ? entry.node.children.map((c) => c.sid) : null;
166
+ };
167
+ for (const sid of present) {
168
+ const bKids = (kidsOf(bIdx, sid) ?? []).filter((id) => present.has(id));
169
+ const lKidsRaw = kidsOf(lIdx, sid);
170
+ const rKidsRaw = kidsOf(rIdx, sid);
171
+ const lKids = (lKidsRaw ?? bKids).filter((id) => present.has(id));
172
+ const rKids = (rKidsRaw ?? bKids).filter((id) => present.has(id));
173
+ const movedL = movedIds(bKids, lKids);
174
+ const movedR = movedIds(bKids, rKids);
175
+ const movedBoth = [...movedL].filter((id) => movedR.has(id));
176
+ // The same child moved differently on both sides is a same-prop-class conflict.
177
+ for (const id of movedBoth) {
178
+ if (lKids.indexOf(id) !== rKids.indexOf(id)) {
179
+ conflicts.push({
180
+ sid,
181
+ reason: 'same-prop',
182
+ props: ['children'],
183
+ detail: `child ${id} moved differently on both sides`,
184
+ });
185
+ }
186
+ }
187
+ // Start from base survivors present on both sides, apply remote moves, then
188
+ // local moves, then insertions from each side at their anchored positions.
189
+ const order = bKids.filter((id) => lKids.includes(id) && rKids.includes(id));
190
+ for (const id of rKids)
191
+ if (movedR.has(id) && order.includes(id))
192
+ reposition(order, id, rKids);
193
+ for (const id of lKids)
194
+ if (movedL.has(id) && order.includes(id))
195
+ reposition(order, id, lKids);
196
+ for (const id of rKids)
197
+ if (!order.includes(id))
198
+ reposition(order, id, rKids);
199
+ for (const id of lKids)
200
+ if (!order.includes(id))
201
+ reposition(order, id, lKids);
202
+ mergedKids.set(sid, order);
203
+ }
204
+ // ---- root + tree assembly ----
205
+ const bRoot = base?.sid ?? null;
206
+ const lRoot = local?.sid ?? null;
207
+ const rRoot = remote?.sid ?? null;
208
+ let rootSid;
209
+ if (lRoot === bRoot && rRoot !== bRoot)
210
+ rootSid = rRoot;
211
+ else if (rRoot === bRoot && lRoot !== bRoot)
212
+ rootSid = lRoot;
213
+ else if (lRoot !== bRoot && rRoot !== bRoot && lRoot !== rRoot) {
214
+ conflicts.push({
215
+ sid: bRoot ?? '(root)',
216
+ reason: 'same-prop',
217
+ props: ['root'],
218
+ detail: 'both sides replaced the page root',
219
+ });
220
+ rootSid = rRoot;
221
+ }
222
+ else
223
+ rootSid = lRoot ?? rRoot;
224
+ const build = (sid, seen) => {
225
+ if (seen.has(sid))
226
+ throw new Error(`cycle in merged tree at ${sid}`);
227
+ seen.add(sid);
228
+ const shell = mergedShell.get(sid);
229
+ if (!shell)
230
+ throw new Error(`merged tree references unknown sid ${sid}`);
231
+ const kids = mergedKids.get(sid) ?? [];
232
+ return {
233
+ sid,
234
+ type: shell.type,
235
+ props: shell.props,
236
+ children: kids.map((k) => build(k, seen)),
237
+ };
238
+ };
239
+ const merged = rootSid && present.has(rootSid) ? build(rootSid, new Set()) : null;
240
+ return { merged, conflicts };
241
+ }
242
+ //# sourceMappingURL=threeWay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threeWay.js","sourceRoot":"","sources":["../../src/merge/threeWay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SidEdit } from '@mapples/sid-ast';
2
+ import type { RenderDomNode } from '../types.js';
3
+ export declare function treeToEdits(local: RenderDomNode | null, merged: RenderDomNode | null): SidEdit[];
@@ -0,0 +1,92 @@
1
+ // Translate "the file currently shows `local`, it should show `merged`" into
2
+ // surgical SidEdits for @mapples/sid-ast — so remote changes land in the file
3
+ // without touching user code. Edit order matters: removals first (so a
4
+ // reparented sid is gone before its new parent inserts it), then shell
5
+ // updates, insertions, and reorders.
6
+ import { indexTree } from './diff.js';
7
+ import { deepEqual } from './mergePatch.js';
8
+ export function treeToEdits(local, merged) {
9
+ const lIdx = indexTree(local);
10
+ const mIdx = indexTree(merged);
11
+ if (local && merged && local.sid !== merged.sid) {
12
+ // Root replaced: one subtree swap.
13
+ return [{ kind: 'replaceSubtree', sid: local.sid, node: merged }];
14
+ }
15
+ const removes = [];
16
+ const shells = [];
17
+ const inserts = [];
18
+ const moves = [];
19
+ // Removals: local nodes that vanished from merged, or were reparented (their
20
+ // new parent re-inserts the merged subtree). Only topmost removals needed.
21
+ for (const [sid, lEntry] of lIdx) {
22
+ const parentRemoved = lEntry.parentSid !== null &&
23
+ (!mIdx.has(lEntry.parentSid) ||
24
+ (lIdx.has(lEntry.parentSid) && removedOrReparented(lEntry.parentSid, lIdx, mIdx)));
25
+ if (parentRemoved)
26
+ continue;
27
+ if (removedOrReparented(sid, lIdx, mIdx)) {
28
+ removes.push({ kind: 'removeNode', sid });
29
+ }
30
+ }
31
+ // Is this local node (or an ancestor) getting removed/re-inserted wholesale?
32
+ const insideRemoved = (sid) => {
33
+ let cursor = sid;
34
+ while (cursor !== null) {
35
+ if (removedOrReparented(cursor, lIdx, mIdx))
36
+ return true;
37
+ cursor = lIdx.get(cursor)?.parentSid ?? null;
38
+ }
39
+ return false;
40
+ };
41
+ for (const [sid, mEntry] of mIdx) {
42
+ const lEntry = lIdx.get(sid);
43
+ if (lEntry && !insideRemoved(sid)) {
44
+ const typeChanged = lEntry.node.type !== mEntry.node.type;
45
+ if (typeChanged || !deepEqual(lEntry.node.props, mEntry.node.props)) {
46
+ shells.push({
47
+ kind: 'setProps',
48
+ sid,
49
+ props: mEntry.node.props,
50
+ ...(typeChanged ? { type: mEntry.node.type } : {}),
51
+ });
52
+ }
53
+ }
54
+ }
55
+ // Insertions + reorders per parent present in both trees.
56
+ for (const [sid, mEntry] of mIdx) {
57
+ const lEntry = lIdx.get(sid);
58
+ if (!lEntry || insideRemoved(sid))
59
+ continue;
60
+ const lKids = lEntry.node.children.map((c) => c.sid);
61
+ const mKids = mEntry.node.children.map((c) => c.sid);
62
+ for (const kid of mKids) {
63
+ const isChildHereAlready = lKids.includes(kid) && !removedOrReparented(kid, lIdx, mIdx);
64
+ if (!isChildHereAlready) {
65
+ inserts.push({
66
+ kind: 'insertChild',
67
+ parentSid: sid,
68
+ at: mKids.indexOf(kid),
69
+ node: mIdx.get(kid).node,
70
+ });
71
+ }
72
+ }
73
+ const surviving = lKids.filter((k) => mKids.includes(k) && !removedOrReparented(k, lIdx, mIdx));
74
+ const targetOrder = mKids.filter((k) => surviving.includes(k));
75
+ if (!deepEqual(surviving, targetOrder)) {
76
+ for (let i = 0; i < mKids.length; i++) {
77
+ moves.push({ kind: 'moveChild', parentSid: sid, sid: mKids[i], to: i });
78
+ }
79
+ }
80
+ }
81
+ return [...removes, ...shells, ...inserts, ...moves];
82
+ }
83
+ function removedOrReparented(sid, lIdx, mIdx) {
84
+ const lEntry = lIdx.get(sid);
85
+ const mEntry = mIdx.get(sid);
86
+ if (!lEntry)
87
+ return false;
88
+ if (!mEntry)
89
+ return true;
90
+ return lEntry.parentSid !== mEntry.parentSid;
91
+ }
92
+ //# sourceMappingURL=toEdits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toEdits.js","sourceRoot":"","sources":["../../src/merge/toEdits.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { NavigationDocument } from '../api/objects.js';
2
+ import type { PagesMap } from '../project/pagesMap.js';
3
+ import type { JpatchOp } from '../types.js';
4
+ import type { SyncReport } from '../ui/report.js';
5
+ export declare function routePathToFile(routePath: string): string;
6
+ export declare function fileToRoutePath(relFile: string): string;
7
+ export interface NavSyncResult {
8
+ pushOps: JpatchOp[];
9
+ mergedNavigation: NavigationDocument | null;
10
+ }
11
+ export declare function syncNavigation(root: string, routesDir: string, pagesMap: PagesMap, base: NavigationDocument | null, remote: NavigationDocument | null, report: SyncReport): NavSyncResult;
@@ -0,0 +1,182 @@
1
+ // NavigationDocument <-> app/(mapples)/ route tree. Contract ported from
2
+ // @mapples/cli: layout files are CLI-OWNED (regenerated every sync), route
3
+ // wrapper files are CREATE-ONCE (the user may edit their content; only their
4
+ // PATH syncs — renaming a wrapper renames the route in Creator and vice versa).
5
+ import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmdirSync, writeFileSync, } from 'node:fs';
6
+ import { dirname, join, posix, relative, sep } from 'node:path';
7
+ import { deprecateFile } from '../merge/deprecate.js';
8
+ const ROUTE_MARKER = /\/\/\s*mapples-route:\s*([A-Za-z0-9_]+)/;
9
+ export function routePathToFile(routePath) {
10
+ const clean = routePath.replace(/^\/+/, '').replace(/\/+$/, '');
11
+ return clean === '' ? 'index.tsx' : `${clean}.tsx`;
12
+ }
13
+ export function fileToRoutePath(relFile) {
14
+ const noExt = relFile
15
+ .replace(/\.tsx$/, '')
16
+ .split(sep)
17
+ .join('/');
18
+ return noExt === 'index' ? '/' : `/${noExt}`;
19
+ }
20
+ function wrapperContent(routeId, routeName, importTarget) {
21
+ return [
22
+ `// mapples-route: ${routeId} — "${routeName}". Created once by Mapples; edit freely.`,
23
+ '// Renaming this file renames the route in Creator on the next `mapples sync`.',
24
+ `export { default } from '${importTarget}';`,
25
+ '',
26
+ ].join('\n');
27
+ }
28
+ function layoutContent() {
29
+ return [
30
+ '// GENERATED by Mapples — DO NOT EDIT. This layout is owned by the CLI;',
31
+ '// it is regenerated from the navigation entity on every `mapples sync`.',
32
+ "import { Stack } from 'expo-router';",
33
+ '',
34
+ 'export default function MapplesLayout() {',
35
+ ' return <Stack />;',
36
+ '}',
37
+ '',
38
+ ].join('\n');
39
+ }
40
+ function scanWrappers(root, routesDir) {
41
+ // routeId -> relative file (within routesDir)
42
+ const found = new Map();
43
+ const dir = join(root, routesDir);
44
+ if (!existsSync(dir))
45
+ return found;
46
+ const walk = (rel) => {
47
+ for (const entry of readdirSync(join(dir, rel), { withFileTypes: true })) {
48
+ const relPath = rel ? join(rel, entry.name) : entry.name;
49
+ if (entry.isDirectory())
50
+ walk(relPath);
51
+ else if (entry.name.endsWith('.tsx') &&
52
+ entry.name !== '_layout.tsx' &&
53
+ !entry.name.startsWith('_depr_')) {
54
+ const match = ROUTE_MARKER.exec(readFileSync(join(dir, relPath), 'utf8'));
55
+ if (match?.[1])
56
+ found.set(match[1], relPath);
57
+ }
58
+ }
59
+ };
60
+ walk('');
61
+ return found;
62
+ }
63
+ export function syncNavigation(root, routesDir, pagesMap, base, remote, report) {
64
+ const baseRoutes = new Map((base?.routes ?? []).map((r) => [r.id, r]));
65
+ const remoteRoutes = new Map((remote?.routes ?? []).map((r) => [r.id, r]));
66
+ const localFiles = scanWrappers(root, routesDir);
67
+ const pushOps = [];
68
+ const mergedRoutes = [];
69
+ const dir = join(root, routesDir);
70
+ const anyRoutes = baseRoutes.size > 0 || remoteRoutes.size > 0 || localFiles.size > 0;
71
+ if (!anyRoutes)
72
+ return { pushOps: [], mergedNavigation: remote ?? base };
73
+ // Layout: CLI-owned, always regenerated.
74
+ mkdirSync(dir, { recursive: true });
75
+ const layoutPath = join(dir, '_layout.tsx');
76
+ const layout = layoutContent();
77
+ if (!existsSync(layoutPath) || readFileSync(layoutPath, 'utf8') !== layout) {
78
+ writeFileSync(layoutPath, layout);
79
+ report.files.push({
80
+ file: join(routesDir, '_layout.tsx'),
81
+ action: 'updated',
82
+ detail: 'CLI-owned layout',
83
+ });
84
+ }
85
+ for (const [id, remoteRoute] of remoteRoutes) {
86
+ const baseRoute = baseRoutes.get(id) ?? null;
87
+ const localFile = localFiles.get(id) ?? null;
88
+ const localPath = localFile ? fileToRoutePath(localFile) : null;
89
+ const basePath = baseRoute?.path ?? null;
90
+ const remotePath = remoteRoute.path;
91
+ const localChanged = localPath !== null && basePath !== null && localPath !== basePath;
92
+ const remoteChanged = basePath !== null && remotePath !== basePath;
93
+ let finalPath = remotePath;
94
+ if (localChanged && remoteChanged && localPath !== remotePath) {
95
+ // Same route renamed differently on both sides: remote wins; local file deprecated.
96
+ report.conflicts.push({
97
+ file: join(routesDir, localFile),
98
+ sid: id,
99
+ reason: 'same-prop',
100
+ props: ['path'],
101
+ localValue: localPath,
102
+ remoteValue: remotePath,
103
+ detail: `route renamed on both sides (${localPath} vs ${remotePath})`,
104
+ });
105
+ const deprecated = relative(root, deprecateFile(join(dir, localFile)));
106
+ report.files.push({
107
+ file: join(routesDir, localFile),
108
+ action: 'deprecated',
109
+ detail: `kept at ${deprecated}`,
110
+ });
111
+ localFiles.delete(id);
112
+ }
113
+ else if (localChanged && (!remoteChanged || localPath === remotePath)) {
114
+ finalPath = localPath;
115
+ if (localPath !== remotePath) {
116
+ pushOps.push({ op: 'update', entity: 'NavigationRoute', id, patch: { path: localPath } });
117
+ }
118
+ }
119
+ const targetFile = routePathToFile(finalPath);
120
+ const targetAbs = join(dir, targetFile);
121
+ const pageMapping = remoteRoute.pageId ? pagesMap[remoteRoute.pageId] : undefined;
122
+ const importTarget = pageMapping
123
+ ? posix.join(...relative(dirname(targetAbs), join(root, pageMapping.file.replace(/\.tsx$/, ''))).split(sep))
124
+ : null;
125
+ const currentFile = localFiles.get(id);
126
+ if (currentFile && currentFile !== targetFile) {
127
+ // Wrapper exists elsewhere: RENAME it (create-once — content is the user's).
128
+ mkdirSync(dirname(targetAbs), { recursive: true });
129
+ renameSync(join(dir, currentFile), targetAbs);
130
+ report.files.push({
131
+ file: join(routesDir, targetFile),
132
+ action: 'updated',
133
+ detail: `route moved from ${fileToRoutePath(currentFile)} to ${finalPath}`,
134
+ });
135
+ pruneEmptyDirs(dir, dirname(currentFile));
136
+ }
137
+ else if (!currentFile && !existsSync(targetAbs)) {
138
+ if (!importTarget) {
139
+ report.notes.push(`route ${id} (${finalPath}) has no page mapping — wrapper not created`);
140
+ }
141
+ else {
142
+ mkdirSync(dirname(targetAbs), { recursive: true });
143
+ writeFileSync(targetAbs, wrapperContent(id, remoteRoute.name, importTarget.startsWith('.') ? importTarget : `./${importTarget}`));
144
+ report.files.push({ file: join(routesDir, targetFile), action: 'created' });
145
+ }
146
+ }
147
+ mergedRoutes.push({ ...remoteRoute, path: finalPath });
148
+ }
149
+ // Routes deleted remotely: deprecate their wrappers (never delete).
150
+ for (const [id, file] of localFiles) {
151
+ if (remoteRoutes.has(id))
152
+ continue;
153
+ if (baseRoutes.has(id)) {
154
+ const deprecated = relative(root, deprecateFile(join(dir, file)));
155
+ report.files.push({
156
+ file: join(routesDir, file),
157
+ action: 'deprecated',
158
+ detail: `route deleted in Creator — wrapper kept at ${deprecated}`,
159
+ });
160
+ }
161
+ else {
162
+ // A wrapper whose route id is unknown to base AND remote: leave it, warn.
163
+ report.notes.push(`wrapper ${join(routesDir, file)} references unknown route id ${id} — left untouched`);
164
+ }
165
+ }
166
+ const mergedNavigation = {
167
+ routes: mergedRoutes,
168
+ layouts: remote?.layouts ?? base?.layouts ?? {},
169
+ };
170
+ return { pushOps, mergedNavigation };
171
+ }
172
+ function pruneEmptyDirs(rootDir, rel) {
173
+ let cursor = rel;
174
+ while (cursor && cursor !== '.') {
175
+ const abs = join(rootDir, cursor);
176
+ if (!existsSync(abs) || readdirSync(abs).length > 0)
177
+ return;
178
+ rmdirSync(abs);
179
+ cursor = dirname(cursor);
180
+ }
181
+ }
182
+ //# sourceMappingURL=routeTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeTree.js","sourceRoot":"","sources":["../../src/nav/routeTree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { RenderDomNode } from '../types.js';
2
+ import type { AssetIndex, NavigationDocument, PageEntity, ComponentEntity, StyleConfig } from '../api/objects.js';
3
+ export interface BaseSnapshot {
4
+ pages: Map<string, PageEntity>;
5
+ components: Map<string, ComponentEntity>;
6
+ navigation: NavigationDocument | null;
7
+ style: StyleConfig | null;
8
+ assets: AssetIndex | null;
9
+ }
10
+ export declare class BaseStore {
11
+ private readonly root;
12
+ constructor(root: string);
13
+ private get dir();
14
+ exists(): boolean;
15
+ readAll(): BaseSnapshot;
16
+ readPageRoot(pageId: string): RenderDomNode | null;
17
+ /** Atomic: write everything into base.tmp, then rename over base. */
18
+ writeAll(snapshot: BaseSnapshot): void;
19
+ }