mapples 0.2.0-beta.1 → 0.2.0-beta.4

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 (93) hide show
  1. package/README.md +70 -22
  2. package/dist/adopt/scan.d.ts +8 -2
  3. package/dist/adopt/scan.js +31 -13
  4. package/dist/adopt/scan.js.map +1 -1
  5. package/dist/api/client.d.ts +9 -1
  6. package/dist/api/client.js +21 -2
  7. package/dist/api/client.js.map +1 -1
  8. package/dist/api/commit.d.ts +9 -0
  9. package/dist/api/commit.js +32 -2
  10. package/dist/api/commit.js.map +1 -1
  11. package/dist/api/errors.js +8 -0
  12. package/dist/api/errors.js.map +1 -1
  13. package/dist/api/objects.d.ts +24 -5
  14. package/dist/api/objects.js +174 -10
  15. package/dist/api/objects.js.map +1 -1
  16. package/dist/api/poll.d.ts +5 -3
  17. package/dist/api/poll.js +17 -6
  18. package/dist/api/poll.js.map +1 -1
  19. package/dist/assets/assets.d.ts +9 -0
  20. package/dist/assets/assets.js +33 -4
  21. package/dist/assets/assets.js.map +1 -1
  22. package/dist/codegen/emit.d.ts +4 -7
  23. package/dist/codegen/emit.js +10 -29
  24. package/dist/codegen/emit.js.map +1 -1
  25. package/dist/codegen/imports.d.ts +1 -15
  26. package/dist/codegen/imports.js +2 -78
  27. package/dist/codegen/imports.js.map +1 -1
  28. package/dist/codegen/instances.d.ts +5 -0
  29. package/dist/codegen/instances.js +30 -0
  30. package/dist/codegen/instances.js.map +1 -0
  31. package/dist/codegen/styles.d.ts +1 -0
  32. package/dist/codegen/styles.js +3 -0
  33. package/dist/codegen/styles.js.map +1 -0
  34. package/dist/commands/impl/createImpl.js +8 -4
  35. package/dist/commands/impl/createImpl.js.map +1 -1
  36. package/dist/commands/impl/initImpl.js +5 -4
  37. package/dist/commands/impl/initImpl.js.map +1 -1
  38. package/dist/commands/impl/syncImpl.js +20 -2
  39. package/dist/commands/impl/syncImpl.js.map +1 -1
  40. package/dist/merge/applyOps.d.ts +1 -1
  41. package/dist/merge/applyOps.js +33 -2
  42. package/dist/merge/applyOps.js.map +1 -1
  43. package/dist/merge/diff.d.ts +1 -1
  44. package/dist/merge/diff.js +30 -17
  45. package/dist/merge/diff.js.map +1 -1
  46. package/dist/merge/threeWay.d.ts +2 -2
  47. package/dist/merge/threeWay.js +38 -6
  48. package/dist/merge/threeWay.js.map +1 -1
  49. package/dist/merge/toEdits.d.ts +1 -3
  50. package/dist/merge/toEdits.js +3 -91
  51. package/dist/merge/toEdits.js.map +1 -1
  52. package/dist/nav/navigatorTree.d.ts +78 -0
  53. package/dist/nav/navigatorTree.js +410 -0
  54. package/dist/nav/navigatorTree.js.map +1 -0
  55. package/dist/nav/placement.d.ts +53 -0
  56. package/dist/nav/placement.js +260 -0
  57. package/dist/nav/placement.js.map +1 -0
  58. package/dist/nav/routeTree.d.ts +8 -2
  59. package/dist/nav/routeTree.js +79 -151
  60. package/dist/nav/routeTree.js.map +1 -1
  61. package/dist/nav/screenOptions.d.ts +15 -0
  62. package/dist/nav/screenOptions.js +213 -0
  63. package/dist/nav/screenOptions.js.map +1 -0
  64. package/dist/project/baseStore.d.ts +19 -1
  65. package/dist/project/baseStore.js +28 -0
  66. package/dist/project/baseStore.js.map +1 -1
  67. package/dist/project/componentsMap.d.ts +7 -0
  68. package/dist/project/componentsMap.js +21 -0
  69. package/dist/project/componentsMap.js.map +1 -0
  70. package/dist/project/config.d.ts +12 -3
  71. package/dist/project/config.js +11 -2
  72. package/dist/project/config.js.map +1 -1
  73. package/dist/project/env.d.ts +10 -3
  74. package/dist/project/env.js +23 -5
  75. package/dist/project/env.js.map +1 -1
  76. package/dist/project/pagesMap.d.ts +2 -0
  77. package/dist/project/pagesMap.js.map +1 -1
  78. package/dist/services/adoptService.d.ts +3 -0
  79. package/dist/services/adoptService.js +346 -38
  80. package/dist/services/adoptService.js.map +1 -1
  81. package/dist/services/clientFactory.js +4 -2
  82. package/dist/services/clientFactory.js.map +1 -1
  83. package/dist/services/doctorService.js +77 -66
  84. package/dist/services/doctorService.js.map +1 -1
  85. package/dist/services/syncEngine.d.ts +7 -0
  86. package/dist/services/syncEngine.js +657 -300
  87. package/dist/services/syncEngine.js.map +1 -1
  88. package/dist/types.d.ts +40 -2
  89. package/dist/types.js +25 -0
  90. package/dist/types.js.map +1 -1
  91. package/package.json +3 -2
  92. package/templates/app/_layout.tsx +3 -0
  93. package/templates/mapples/sid.d.ts +6 -0
@@ -1,24 +1,188 @@
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, navigation, style, assets] = await Promise.all([
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
- await Promise.all(Object.entries(pagesIndex).map(async ([id, hash]) => {
13
- const blob = (await client.getObject(hash));
14
- pages.set(id, { id, ...blob });
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
- await Promise.all(Object.entries(componentsIndex).map(async ([id, hash]) => {
18
- const blob = (await client.getObject(hash));
19
- components.set(id, { id, ...blob });
20
- }));
21
- return { head: boot.head, seq: boot.seq, pages, components, navigation, style, assets };
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
+ sources: await fetchSources(client, boot),
163
+ };
164
+ }
165
+ /** The `sources` index (RFC-0001 A12), keyed by container id; empty when the manifest has none. */
166
+ async function fetchSources(client, boot) {
167
+ const sources = new Map();
168
+ if (boot.manifest.sources === undefined)
169
+ return sources;
170
+ const index = (await client.getObject(boot.manifest.sources));
171
+ const blobs = await fetchObjects(client, Object.values(index));
172
+ for (const [indexId, hash] of Object.entries(index)) {
173
+ const blob = blobs.get(hash);
174
+ if (typeof blob.of !== 'string' || typeof blob.text !== 'string') {
175
+ throw new Error(`source blob ${indexId} is missing of/text — schema drift, update the CLI`);
176
+ }
177
+ sources.set(blob.of, {
178
+ id: blob.id ?? indexId,
179
+ of: blob.of,
180
+ lang: typeof blob.lang === 'string' ? blob.lang : 'tsx',
181
+ text: blob.text,
182
+ ...(typeof blob.docHash === 'string' ? { docHash: blob.docHash } : {}),
183
+ });
184
+ }
185
+ return sources;
22
186
  }
23
187
  /**
24
188
  * Upload binary asset bodies: `objects/have` filters to genuinely missing
@@ -1 +1 @@
1
- {"version":3,"file":"objects.js","sourceRoot":"","sources":["../../src/api/objects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AA4D1B,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAoB,EACpB,IAAe;IAEf,MAAM,CAAC,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACjF,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAoC;QACxE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAoC;QAC7E,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAgC;QACzE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAyB;QAC7D,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAwB;KAC9D,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC5C,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;QAClD,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAA2B,CAAC;QACtE,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;IACjC,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,GAAG,EAA2B,CAAC;IACtD,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;QACvD,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAgC,CAAC;QAC3E,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC1F,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAoB,EACpB,MAAwD;IAExD,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAC5D,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,sDAAsD,IAAI,EAAE,CAAC,CAAC;YACzF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE;gBAC9C,OAAO,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,IAAI,EAAE;gBACtC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI;aAC3B,CAAC,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,CAAC,MAAM,SAAS,IAAI,EAAE,CAAC,CAAC;YAC1E,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"objects.js","sourceRoot":"","sources":["../../src/api/objects.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,9 @@ export declare class SnapshotRequired extends Error {
4
4
  constructor();
5
5
  }
6
6
  /**
7
- * Pull the full delta since `head`, following `truncated: true` pages until
8
- * exhausted (RFC-0001 §6). Throws SnapshotRequired when the server signals it.
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, since: string): Promise<Delta>;
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 `head`, following `truncated: true` pages until
10
- * exhausted (RFC-0001 §6). Throws SnapshotRequired when the server signals it.
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, since) {
14
+ export async function pullDelta(client, sinceSeq) {
13
15
  const ops = [];
14
- let cursor = since;
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
- cursor = page.head;
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
@@ -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;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAoB,EAAE,KAAa;IACjE,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,SAAS,CAAC;QACR,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,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,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;AACH,CAAC"}
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"}
@@ -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;
@@ -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 = meta.name ?? `${id}${EXT_BY_MIME[meta.mime] ?? ''}`;
51
+ const fileName = assetFileName(id, meta);
33
52
  const filePath = join(dir, fileName);
34
53
  if (existsSync(filePath))
35
54
  continue;
36
- const bytes = await client.getObjectBytes(`sha256:${meta.sha256}`);
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.name ?? id}'),`);
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":"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"}
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/assets/assets.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,5 @@
1
- import type { RenderDomNode } from '../types.js';
2
- export declare const GENERATED_HEADER: string;
3
- export declare function mappletName(pageName: string): string;
4
- export interface EmitPageInput {
5
- name: string;
6
- root: RenderDomNode;
7
- }
1
+ import { type EmitComponentInput, type EmitPageInput } from '@mapples/codegen';
2
+ export { COMPONENT_HEADER, GENERATED_HEADER, pageComponentName, readRouteMarker, ROUTE_MARKER, routeMarkerLine, withoutRouteMarker, withRouteMarker, type EmitComponentInput, type EmitPageInput, } from '@mapples/codegen';
8
3
  export declare function emitPage(page: EmitPageInput, filePath?: string): Promise<string>;
4
+ /** A Creator component as a file: same shape as a page, no route. */
5
+ export declare function emitComponent(component: EmitComponentInput, filePath?: string): Promise<string>;
@@ -1,33 +1,14 @@
1
- // RenderDom page -> complete *Mapplet.tsx. Deterministic: stable prop order
2
- // (sid-ast printer), stable import order, Prettier-formatted.
3
- import { printNode } from '@mapples/sid-ast';
4
- import { collectImports, printImports } from './imports.js';
1
+ // RenderDom page -> complete page file, Prettier-formatted with the target
2
+ // project's config. The generation itself lives in @mapples/codegen (pure),
3
+ // shared with the Creator's code editor; this module adds the formatting.
4
+ import { emitComponent as emitComponentText, emitPage as emitPageText, } from '@mapples/codegen';
5
5
  import { formatTsx } from './format.js';
6
- export const GENERATED_HEADER = '// Generated by Mapples — edit freely, but keep the $sid props intact.\n' +
7
- '// Two-way sync: `mapples sync` reconciles this file with Mapples Creator.';
8
- export function mappletName(pageName) {
9
- const pascal = pageName
10
- .split(/[^A-Za-z0-9]+/)
11
- .filter(Boolean)
12
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
13
- .join('');
14
- return `${pascal || 'Page'}Mapplet`;
15
- }
6
+ export { COMPONENT_HEADER, GENERATED_HEADER, pageComponentName, readRouteMarker, ROUTE_MARKER, routeMarkerLine, withoutRouteMarker, withRouteMarker, } from '@mapples/codegen';
16
7
  export async function emitPage(page, filePath) {
17
- const imports = collectImports(page.root);
18
- const jsx = printNode(page.root, ' ');
19
- const code = [
20
- GENERATED_HEADER,
21
- '',
22
- printImports(imports),
23
- '',
24
- `export default function ${mappletName(page.name)}() {`,
25
- ' return (',
26
- jsx,
27
- ' );',
28
- '}',
29
- '',
30
- ].join('\n');
31
- return formatTsx(code, filePath);
8
+ return formatTsx(emitPageText(page), filePath);
9
+ }
10
+ /** A Creator component as a file: same shape as a page, no route. */
11
+ export async function emitComponent(component, filePath) {
12
+ return formatTsx(emitComponentText(component), filePath);
32
13
  }
33
14
  //# sourceMappingURL=emit.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/codegen/emit.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8DAA8D;AAE9D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,CAAC,MAAM,gBAAgB,GAC3B,0EAA0E;IAC1E,4EAA4E,CAAC;AAE/E,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,MAAM,GAAG,QAAQ;SACpB,KAAK,CAAC,eAAe,CAAC;SACtB,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,GAAG,MAAM,IAAI,MAAM,SAAS,CAAC;AACtC,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAmB,EAAE,QAAiB;IACnE,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG;QACX,gBAAgB;QAChB,EAAE;QACF,YAAY,CAAC,OAAO,CAAC;QACrB,EAAE;QACF,2BAA2B,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;QACvD,YAAY;QACZ,GAAG;QACH,MAAM;QACN,GAAG;QACH,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/codegen/emit.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,4EAA4E;AAC5E,0EAA0E;AAE1E,OAAO,EACL,aAAa,IAAI,iBAAiB,EAClC,QAAQ,IAAI,YAAY,GAGzB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,eAAe,GAGhB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAmB,EAAE,QAAiB;IACnE,OAAO,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,SAA6B,EAC7B,QAAiB;IAEjB,OAAO,SAAS,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC3D,CAAC"}
@@ -1,15 +1 @@
1
- import type { RenderDomNode } from '../types.js';
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;
1
+ export { collectImports, importNeedsFor, parseImportRef, printImports, UI_MODULE, type ResolvedImports, } from '@mapples/codegen';
@@ -1,79 +1,3 @@
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
- }
1
+ // The import block of a generated file — lives in @mapples/codegen (pure).
2
+ export { collectImports, importNeedsFor, parseImportRef, printImports, UI_MODULE, } from '@mapples/codegen';
79
3
  //# sourceMappingURL=imports.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"imports.js","sourceRoot":"","sources":["../../src/codegen/imports.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"imports.js","sourceRoot":"","sources":["../../src/codegen/imports.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,SAAS,GAEV,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type InstanceLinker } from '@mapples/codegen';
2
+ import type { ComponentEntity } from '../api/objects.js';
3
+ import type { ComponentsMap } from '../project/componentsMap.js';
4
+ export type { InstanceLinker } from '@mapples/codegen';
5
+ export declare function instanceLinker(componentsMap: ComponentsMap, components: Map<string, ComponentEntity>): InstanceLinker;
@@ -0,0 +1,30 @@
1
+ // Linked component instances (file language <-> canvas language) — the
2
+ // conversion lives in @mapples/codegen; this binds it to the CLI's
3
+ // components map and to `node:path`, so OS-native paths in the map resolve
4
+ // the way they always did.
5
+ import { dirname, posix, relative, sep } from 'node:path';
6
+ import { instanceLinker as linker, } from '@mapples/codegen';
7
+ const toPosix = (p) => p.split(sep).join(posix.sep);
8
+ /** `node:path`-backed resolver over the project's OS paths. */
9
+ const nodeResolver = {
10
+ fileFor(fromFile, module) {
11
+ if (!module.startsWith('.'))
12
+ return null;
13
+ const resolved = posix.normalize(posix.join(toPosix(dirname(fromFile)), module));
14
+ return resolved.endsWith('.tsx') ? resolved : `${resolved}.tsx`;
15
+ },
16
+ moduleFor(fromFile, targetFile) {
17
+ let rel = toPosix(relative(dirname(fromFile), targetFile)).replace(/\.tsx$/, '');
18
+ if (!rel.startsWith('.'))
19
+ rel = `./${rel}`;
20
+ return rel;
21
+ },
22
+ };
23
+ export function instanceLinker(componentsMap, components) {
24
+ const posixMap = {};
25
+ for (const [id, mapping] of Object.entries(componentsMap)) {
26
+ posixMap[id] = { file: toPosix(mapping.file), name: mapping.name };
27
+ }
28
+ return linker(posixMap, components, nodeResolver);
29
+ }
30
+ //# sourceMappingURL=instances.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instances.js","sourceRoot":"","sources":["../../src/codegen/instances.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,mEAAmE;AACnE,2EAA2E;AAC3E,2BAA2B;AAE3B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAE1D,OAAO,EACL,cAAc,IAAI,MAAM,GAGzB,MAAM,kBAAkB,CAAC;AAO1B,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAEpE,+DAA+D;AAC/D,MAAM,YAAY,GAAmB;IACnC,OAAO,CAAC,QAAQ,EAAE,MAAM;QACtB,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACjF,OAAO,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,MAAM,CAAC;IAClE,CAAC;IACD,SAAS,CAAC,QAAQ,EAAE,UAAU;QAC5B,IAAI,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACjF,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,GAAG,GAAG,KAAK,GAAG,EAAE,CAAC;QAC3C,OAAO,GAAG,CAAC;IACb,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,cAAc,CAC5B,aAA4B,EAC5B,UAAwC;IAExC,MAAM,QAAQ,GAAmD,EAAE,CAAC;IACpE,KAAK,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QAC1D,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;IACrE,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1 @@
1
+ export { hoistStyles, STYLE_MODULE, type HoistedStyles } from '@mapples/codegen';
@@ -0,0 +1,3 @@
1
+ // Hoisted `Styler.create` dictionaries — live in @mapples/codegen (pure).
2
+ export { hoistStyles, STYLE_MODULE } from '@mapples/codegen';
3
+ //# sourceMappingURL=styles.js.map