mapples 0.2.0-beta.3 → 0.2.0-beta.5

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 (43) hide show
  1. package/dist/api/objects.d.ts +3 -1
  2. package/dist/api/objects.js +24 -1
  3. package/dist/api/objects.js.map +1 -1
  4. package/dist/api/txPlan.d.ts +15 -0
  5. package/dist/api/txPlan.js +196 -0
  6. package/dist/api/txPlan.js.map +1 -0
  7. package/dist/codegen/emit.d.ts +2 -31
  8. package/dist/codegen/emit.js +7 -147
  9. package/dist/codegen/emit.js.map +1 -1
  10. package/dist/codegen/imports.d.ts +1 -17
  11. package/dist/codegen/imports.js +2 -116
  12. package/dist/codegen/imports.js.map +1 -1
  13. package/dist/codegen/instances.d.ts +2 -13
  14. package/dist/codegen/instances.js +23 -134
  15. package/dist/codegen/instances.js.map +1 -1
  16. package/dist/codegen/styles.d.ts +1 -11
  17. package/dist/codegen/styles.js +2 -130
  18. package/dist/codegen/styles.js.map +1 -1
  19. package/dist/merge/applyOps.d.ts +4 -1
  20. package/dist/merge/applyOps.js +42 -30
  21. package/dist/merge/applyOps.js.map +1 -1
  22. package/dist/merge/childrenOrder.d.ts +13 -0
  23. package/dist/merge/childrenOrder.js +51 -0
  24. package/dist/merge/childrenOrder.js.map +1 -0
  25. package/dist/merge/threeWay.d.ts +1 -1
  26. package/dist/merge/toEdits.d.ts +1 -3
  27. package/dist/merge/toEdits.js +3 -94
  28. package/dist/merge/toEdits.js.map +1 -1
  29. package/dist/project/baseStore.d.ts +11 -1
  30. package/dist/project/baseStore.js +13 -0
  31. package/dist/project/baseStore.js.map +1 -1
  32. package/dist/services/adoptService.js +11 -0
  33. package/dist/services/adoptService.js.map +1 -1
  34. package/dist/services/syncEngine.d.ts +1 -1
  35. package/dist/services/syncEngine.js +297 -60
  36. package/dist/services/syncEngine.js.map +1 -1
  37. package/dist/types.d.ts +28 -1
  38. package/dist/types.js +3 -0
  39. package/dist/types.js.map +1 -1
  40. package/dist/ui/report.d.ts +7 -0
  41. package/dist/ui/report.js +8 -0
  42. package/dist/ui/report.js.map +1 -1
  43. package/package.json +3 -2
@@ -1,117 +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
- }
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
- }
1
+ // The import block of a generated file — lives in @mapples/codegen (pure).
2
+ export { collectImports, importNeedsFor, parseImportRef, printImports, UI_MODULE, } from '@mapples/codegen';
117
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"}
@@ -1,16 +1,5 @@
1
- import type { ExtractWarning } from '@mapples/sid-ast';
1
+ import { type InstanceLinker } from '@mapples/codegen';
2
2
  import type { ComponentEntity } from '../api/objects.js';
3
3
  import type { ComponentsMap } from '../project/componentsMap.js';
4
- import type { RenderDomNode } from '../types.js';
5
- export interface InstanceLinker {
6
- /** File language -> canvas language, in place. Reports what could not link. */
7
- link(dom: RenderDomNode, file: string, warn: (w: ExtractWarning) => void): void;
8
- /** Canvas language -> file language, as a copy. Reports instances with no component. */
9
- unlink(dom: RenderDomNode, file: string, warn: (w: ExtractWarning) => void): RenderDomNode;
10
- /** Does this import, from this file, name a managed component? */
11
- isLinked(origin: {
12
- module: string;
13
- exportName: string;
14
- }, file: string): boolean;
15
- }
4
+ export type { InstanceLinker } from '@mapples/codegen';
16
5
  export declare function instanceLinker(componentsMap: ComponentsMap, components: Map<string, ComponentEntity>): InstanceLinker;
@@ -1,141 +1,30 @@
1
- // Linked component instances: the two languages a page speaks.
2
- //
3
- // In a FILE, a Creator component used on a page is what a developer writes —
4
- // `import ProfileCard from '../mapples/components/ProfileCard'` and
5
- // `<ProfileCard $sid="…" styled={{ … }} />` — which extraction reads as a
6
- // `Custom` node with that import ref. On the CANVAS the same thing is a
7
- // `ComponentInstance` node: `{ componentUuid, componentName, styled }`, the
8
- // Creator's linked instance of the saved component. Base and remote trees
9
- // always speak canvas; a tree read from a file speaks file. `link` and
10
- // `unlink` convert, so the merge compares like with like and the file never
11
- // sees a `ComponentInstance` tag (nothing exports one).
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.
12
5
  import { dirname, posix, relative, sep } from 'node:path';
13
- import { pageComponentName } from './emit.js';
14
- import { parseImportRef } from './imports.js';
6
+ import { instanceLinker as linker, } from '@mapples/codegen';
15
7
  const toPosix = (p) => p.split(sep).join(posix.sep);
16
- /** `../mapples/components/ProfileCard` from `app/profile.tsx` -> `mapples/components/ProfileCard.tsx`. */
17
- function resolveModuleFile(fromFile, module) {
18
- if (!module.startsWith('.'))
19
- return null;
20
- const resolved = posix.normalize(posix.join(toPosix(dirname(fromFile)), module));
21
- return resolved.endsWith('.tsx') ? resolved : `${resolved}.tsx`;
22
- }
23
- /** `mapples/components/ProfileCard.tsx` from `app/profile.tsx` -> `../mapples/components/ProfileCard`. */
24
- function moduleForFile(fromFile, targetFile) {
25
- let rel = toPosix(relative(dirname(fromFile), targetFile)).replace(/\.tsx$/, '');
26
- if (!rel.startsWith('.'))
27
- rel = `./${rel}`;
28
- return rel;
29
- }
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
+ };
30
23
  export function instanceLinker(componentsMap, components) {
31
- const byFile = new Map();
32
- const byUuid = new Map();
24
+ const posixMap = {};
33
25
  for (const [id, mapping] of Object.entries(componentsMap)) {
34
- const entity = components.get(id);
35
- const linked = {
36
- id,
37
- file: toPosix(mapping.file),
38
- name: entity?.name ?? mapping.name,
39
- uuid: entity?.uuid,
40
- };
41
- byFile.set(linked.file, linked);
42
- if (linked.uuid)
43
- byUuid.set(linked.uuid, linked);
26
+ posixMap[id] = { file: toPosix(mapping.file), name: mapping.name };
44
27
  }
45
- const componentFor = (origin, file) => {
46
- if (origin.exportName !== 'default')
47
- return null;
48
- const target = resolveModuleFile(file, origin.module);
49
- return target ? (byFile.get(target) ?? null) : null;
50
- };
51
- return {
52
- isLinked: (origin, file) => componentFor(origin, file) !== null,
53
- link(dom, file, warn) {
54
- const walk = (node) => {
55
- node.children.forEach(walk);
56
- if (node.type !== 'Custom')
57
- return;
58
- const { name, importRef, layout } = node.props;
59
- if (typeof name !== 'string' || typeof importRef !== 'string')
60
- return;
61
- const component = componentFor(parseImportRef(importRef), file);
62
- if (!component)
63
- return;
64
- if (!component.uuid) {
65
- warn({
66
- kind: 'UNKNOWN_ELEMENT_WITH_SID',
67
- sid: node.sid,
68
- detail: `<${name}> is the Creator component “${component.name}”, but that component has no uuid yet — pushed as a Custom placeholder; run \`mapples sync\` again after the component reaches the Creator`,
69
- });
70
- return;
71
- }
72
- const attrs = (layout ?? {});
73
- const { styled, ...rest } = attrs;
74
- for (const key of Object.keys(rest)) {
75
- warn({
76
- kind: 'NON_LITERAL_PROP',
77
- sid: node.sid,
78
- prop: key,
79
- detail: `prop \`${key}\` on <${name}> stays in code only — a Creator component instance takes no props besides \`styled\``,
80
- });
81
- }
82
- if (node.children.length > 0) {
83
- warn({
84
- kind: 'NON_LITERAL_PROP',
85
- sid: node.sid,
86
- prop: 'children',
87
- detail: `children of <${name}> are not part of the Creator instance — kept in code only`,
88
- });
89
- }
90
- node.type = 'ComponentInstance';
91
- node.props = {
92
- componentUuid: component.uuid,
93
- componentName: component.name,
94
- ...(styled !== undefined ? { styled } : {}),
95
- };
96
- node.children = [];
97
- };
98
- walk(dom);
99
- },
100
- unlink(dom, file, warn) {
101
- // A component the Creator named after its root ("View", "Button"…)
102
- // cannot share a local name with the primitive the file imports.
103
- const primitiveTypes = new Set();
104
- const collectTypes = (node) => {
105
- if (node.type !== 'Custom' && node.type !== 'ComponentInstance') {
106
- primitiveTypes.add(node.type);
107
- }
108
- node.children.forEach(collectTypes);
109
- };
110
- collectTypes(dom);
111
- const localName = (component) => pageComponentName(component.name, primitiveTypes, 'Component');
112
- const convert = (node) => {
113
- const children = node.children.map(convert);
114
- if (node.type !== 'ComponentInstance')
115
- return { ...node, children };
116
- const { componentUuid, componentName, styled } = node.props;
117
- const component = typeof componentUuid === 'string' ? byUuid.get(componentUuid) : undefined;
118
- if (!component) {
119
- warn({
120
- kind: 'UNKNOWN_ELEMENT_WITH_SID',
121
- sid: node.sid,
122
- detail: `instance of component “${String(componentName ?? componentUuid)}” has no component file to import — left as a ComponentInstance tag`,
123
- });
124
- return { ...node, children };
125
- }
126
- return {
127
- ...node,
128
- type: 'Custom',
129
- props: {
130
- name: localName(component),
131
- importRef: `${moduleForFile(file, component.file)}#default`,
132
- layout: styled !== undefined ? { styled } : {},
133
- },
134
- children,
135
- };
136
- };
137
- return convert(dom);
138
- },
139
- };
28
+ return linker(posixMap, components, nodeResolver);
140
29
  }
141
30
  //# sourceMappingURL=instances.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"instances.js","sourceRoot":"","sources":["../../src/codegen/instances.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,EAAE;AACF,6EAA6E;AAC7E,oEAAoE;AACpE,0EAA0E;AAC1E,wEAAwE;AACxE,4EAA4E;AAC5E,0EAA0E;AAC1E,uEAAuE;AACvE,4EAA4E;AAC5E,wDAAwD;AAExD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAQ1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAkB9C,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAEpE,0GAA0G;AAC1G,SAAS,iBAAiB,CAAC,QAAgB,EAAE,MAAc;IACzD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACjF,OAAO,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,MAAM,CAAC;AAClE,CAAC;AAED,0GAA0G;AAC1G,SAAS,aAAa,CAAC,QAAgB,EAAE,UAAkB;IACzD,IAAI,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACjF,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,GAAG,GAAG,KAAK,GAAG,EAAE,CAAC;IAC3C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,aAA4B,EAC5B,UAAwC;IAExC,MAAM,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAC;IAClD,KAAK,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QAC1D,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,MAAM,GAAoB;YAC9B,EAAE;YACF,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;YAC3B,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,OAAO,CAAC,IAAI;YAClC,IAAI,EAAE,MAAM,EAAE,IAAI;SACnB,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,MAAM,CAAC,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,YAAY,GAAG,CACnB,MAA8C,EAC9C,IAAY,EACY,EAAE;QAC1B,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACjD,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACtD,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtD,CAAC,CAAC;IAEF,OAAO;QACL,QAAQ,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,IAAI;QAE/D,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI;YAClB,MAAM,IAAI,GAAG,CAAC,IAAmB,EAAQ,EAAE;gBACzC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC5B,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;oBAAE,OAAO;gBACnC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,KAIxC,CAAC;gBACF,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,SAAS,KAAK,QAAQ;oBAAE,OAAO;gBACtE,MAAM,SAAS,GAAG,YAAY,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;gBAChE,IAAI,CAAC,SAAS;oBAAE,OAAO;gBACvB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;oBACpB,IAAI,CAAC;wBACH,IAAI,EAAE,0BAA0B;wBAChC,GAAG,EAAE,IAAI,CAAC,GAAG;wBACb,MAAM,EAAE,IAAI,IAAI,+BAA+B,SAAS,CAAC,IAAI,4IAA4I;qBAC1M,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBACD,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,EAAE,CAA4B,CAAC;gBACxD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;gBAClC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACpC,IAAI,CAAC;wBACH,IAAI,EAAE,kBAAkB;wBACxB,GAAG,EAAE,IAAI,CAAC,GAAG;wBACb,IAAI,EAAE,GAAG;wBACT,MAAM,EAAE,UAAU,GAAG,UAAU,IAAI,uFAAuF;qBAC3H,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC7B,IAAI,CAAC;wBACH,IAAI,EAAE,kBAAkB;wBACxB,GAAG,EAAE,IAAI,CAAC,GAAG;wBACb,IAAI,EAAE,UAAU;wBAChB,MAAM,EAAE,gBAAgB,IAAI,4DAA4D;qBACzF,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;gBAChC,IAAI,CAAC,KAAK,GAAG;oBACX,aAAa,EAAE,SAAS,CAAC,IAAI;oBAC7B,aAAa,EAAE,SAAS,CAAC,IAAI;oBAC7B,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC5C,CAAC;gBACF,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACrB,CAAC,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC;QAED,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI;YACpB,mEAAmE;YACnE,iEAAiE;YACjE,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;YACzC,MAAM,YAAY,GAAG,CAAC,IAAmB,EAAQ,EAAE;gBACjD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;oBAChE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChC,CAAC;gBACD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YACtC,CAAC,CAAC;YACF,YAAY,CAAC,GAAG,CAAC,CAAC;YAClB,MAAM,SAAS,GAAG,CAAC,SAA0B,EAAU,EAAE,CACvD,iBAAiB,CAAC,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;YAEjE,MAAM,OAAO,GAAG,CAAC,IAAmB,EAAiB,EAAE;gBACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC5C,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB;oBAAE,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC;gBACpE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,KAIrD,CAAC;gBACF,MAAM,SAAS,GAAG,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC5F,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,IAAI,CAAC;wBACH,IAAI,EAAE,0BAA0B;wBAChC,GAAG,EAAE,IAAI,CAAC,GAAG;wBACb,MAAM,EAAE,0BAA0B,MAAM,CAAC,aAAa,IAAI,aAAa,CAAC,qEAAqE;qBAC9I,CAAC,CAAC;oBACH,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC;gBAC/B,CAAC;gBACD,OAAO;oBACL,GAAG,IAAI;oBACP,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE;wBACL,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC;wBAC1B,SAAS,EAAE,GAAG,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU;wBAC3D,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;qBAC/C;oBACD,QAAQ;iBACT,CAAC;YACJ,CAAC,CAAC;YACF,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;KACF,CAAC;AACJ,CAAC"}
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"}
@@ -1,11 +1 @@
1
- import type { RenderDomNode } from '../types.js';
2
- /** Where `Styler` comes from in app code. */
3
- export declare const STYLE_MODULE = "@mapples/style";
4
- export interface HoistedStyles {
5
- dictName: string;
6
- /** Dictionary entries in document order: `[key, style object]`. */
7
- entries: [string, unknown][];
8
- /** The expression a node's `styled` key prints as, or undefined to print the literal. */
9
- refFor: (node: RenderDomNode, key: string, value: unknown) => string | undefined;
10
- }
11
- export declare function hoistStyles(root: RenderDomNode, dictName?: string): HoistedStyles;
1
+ export { hoistStyles, STYLE_MODULE, type HoistedStyles } from '@mapples/codegen';
@@ -1,131 +1,3 @@
1
- // Hoisting generated styles: every object under a node's `styled` becomes an
2
- // entry of one `const styles = Styler.create({…})` dictionary at the bottom
3
- // of the file, and the tag reads `styled={{ style: styles.signInText }}`.
4
- // Keys come from what the element shows (its text, label, placeholder…) and
5
- // what it is, so a developer can find a style by reading the JSX.
6
- /** Where `Styler` comes from in app code. */
7
- export const STYLE_MODULE = '@mapples/style';
8
- /** `styled` keys that hold a style object, and the word appended to the entry key for each. */
9
- const STYLED_SUFFIX = {
10
- style: '',
11
- styleImage: 'Picture',
12
- styleTypography: 'Label',
13
- styleSvg: 'Glyph',
14
- contentContainerStyle: 'Content',
15
- };
16
- /** The word for a node type inside an entry key. */
17
- const TYPE_WORD = {
18
- View: 'view',
19
- SafeAreaView: 'screen',
20
- ScrollView: 'scroll',
21
- FlatList: 'list',
22
- FormView: 'form',
23
- Text: 'text',
24
- Image: 'image',
25
- Button: 'button',
26
- SubmitButton: 'button',
27
- TextInput: 'input',
28
- TextField: 'input',
29
- Vector: 'icon',
30
- Icon: 'icon',
31
- Custom: 'custom',
32
- };
33
- /** Props whose text names an element well enough to name its style. */
34
- const HINT_PROPS = ['text', 'label', 'placeholder', 'title', 'alt', 'fieldName'];
35
- const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
36
- /**
37
- * "Please enter username and password" -> "pleaseEnterUsername". Words are
38
- * letters only — a price like "0.99$" names nothing — and the result is a
39
- * valid identifier start or empty.
40
- */
41
- function hintWords(text) {
42
- const words = text
43
- .replace(/[^A-Za-z ]+/g, ' ')
44
- .split(/\s+/)
45
- .filter(Boolean)
46
- .slice(0, 3)
47
- .map((w) => w.toLowerCase());
48
- if (words.length === 0)
49
- return '';
50
- return words[0] + words.slice(1).map(capitalize).join('');
51
- }
52
- function typeWord(node) {
53
- if (node.type === 'Custom') {
54
- const name = node.props.name;
55
- return typeof name === 'string' && name !== ''
56
- ? name.charAt(0).toLowerCase() + name.slice(1)
57
- : 'custom';
58
- }
59
- return TYPE_WORD[node.type] ?? node.type.charAt(0).toLowerCase() + node.type.slice(1);
60
- }
61
- /**
62
- * The words an element's style keys are built from: `stem` is what it shows
63
- * (`signIn`, `companyLogo`) or what it is when it shows nothing (`view`);
64
- * `style` adds the type to a shown stem (`signInText`), the other `styled`
65
- * keys add their own word to the stem (`signInLabel`, `companyLogoPicture`).
66
- */
67
- function keyWords(node, isRoot) {
68
- if (isRoot)
69
- return { stem: 'root', style: 'root' };
70
- const props = node.type === 'Custom' ? (node.props.layout ?? {}) : node.props;
71
- const type = typeWord(node);
72
- for (const prop of HINT_PROPS) {
73
- const v = props[prop];
74
- if (typeof v === 'string' && v.trim() !== '') {
75
- const hint = hintWords(v);
76
- if (hint !== '')
77
- return { stem: hint, style: `${hint}${capitalize(type)}` };
78
- }
79
- }
80
- return { stem: type, style: type };
81
- }
82
- function styledOf(node) {
83
- const styled = node.type === 'Custom'
84
- ? (node.props.layout ?? {}).styled
85
- : node.props.styled;
86
- return typeof styled === 'object' && styled !== null && !Array.isArray(styled)
87
- ? styled
88
- : null;
89
- }
90
- export function hoistStyles(root, dictName = 'styles') {
91
- const entries = [];
92
- const taken = new Set();
93
- const refs = new Map(); // `${sid}|${styledKey}` -> entry key
94
- const unique = (key) => {
95
- let candidate = key;
96
- for (let n = 2; taken.has(candidate); n += 1)
97
- candidate = `${key}${n}`;
98
- taken.add(candidate);
99
- return candidate;
100
- };
101
- const visit = (node, isRoot) => {
102
- const styled = styledOf(node);
103
- if (styled) {
104
- const words = keyWords(node, isRoot);
105
- for (const [styledKey, value] of Object.entries(styled)) {
106
- if (!(styledKey in STYLED_SUFFIX))
107
- continue;
108
- if (typeof value !== 'object' || value === null || Array.isArray(value))
109
- continue;
110
- if (Object.keys(value).length === 0)
111
- continue;
112
- const suffix = STYLED_SUFFIX[styledKey];
113
- const key = unique(suffix === '' ? words.style : `${words.stem}${suffix}`);
114
- entries.push([key, value]);
115
- refs.set(`${node.sid}|${styledKey}`, key);
116
- }
117
- }
118
- for (const child of node.children)
119
- visit(child, false);
120
- };
121
- visit(root, true);
122
- return {
123
- dictName,
124
- entries,
125
- refFor: (node, key) => {
126
- const entry = refs.get(`${node.sid}|${key}`);
127
- return entry === undefined ? undefined : `${dictName}.${entry}`;
128
- },
129
- };
130
- }
1
+ // Hoisted `Styler.create` dictionaries — live in @mapples/codegen (pure).
2
+ export { hoistStyles, STYLE_MODULE } from '@mapples/codegen';
131
3
  //# sourceMappingURL=styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/codegen/styles.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,4EAA4E;AAC5E,kEAAkE;AAIlE,6CAA6C;AAC7C,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAE7C,+FAA+F;AAC/F,MAAM,aAAa,GAA2B;IAC5C,KAAK,EAAE,EAAE;IACT,UAAU,EAAE,SAAS;IACrB,eAAe,EAAE,OAAO;IACxB,QAAQ,EAAE,OAAO;IACjB,qBAAqB,EAAE,SAAS;CACjC,CAAC;AAEF,oDAAoD;AACpD,MAAM,SAAS,GAA2B;IACxC,IAAI,EAAE,MAAM;IACZ,YAAY,EAAE,QAAQ;IACtB,UAAU,EAAE,QAAQ;IACpB,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,MAAM;IAChB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,YAAY,EAAE,QAAQ;IACtB,SAAS,EAAE,OAAO;IAClB,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,MAAM;IACd,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;CACjB,CAAC;AAEF,uEAAuE;AACvE,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;AAUjF,MAAM,UAAU,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEjF;;;;GAIG;AACH,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,KAAK,GAAG,IAAI;SACf,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;SAC5B,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,OAAO,CAAC;SACf,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,OAAO,KAAK,CAAC,CAAC,CAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,QAAQ,CAAC,IAAmB;IACnC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAC7B,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,EAAE;YAC5C,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9C,CAAC,CAAC,QAAQ,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxF,CAAC;AAED;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,IAAmB,EAAE,MAAe;IACpD,IAAI,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACnD,MAAM,KAAK,GACT,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,MAAkC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IAC/F,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,IAAI,KAAK,EAAE;gBAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QAC9E,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,QAAQ,CAAC,IAAmB;IACnC,MAAM,MAAM,GACV,IAAI,CAAC,IAAI,KAAK,QAAQ;QACpB,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,MAA8C,IAAI,EAAE,CAAC,CAAC,MAAM;QAC3E,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IACxB,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5E,CAAC,CAAE,MAAkC;QACrC,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAmB,EAAE,QAAQ,GAAG,QAAQ;IAClE,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC,CAAC,qCAAqC;IAE7E,MAAM,MAAM,GAAG,CAAC,GAAW,EAAU,EAAE;QACrC,IAAI,SAAS,GAAG,GAAG,CAAC;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC;YAAE,SAAS,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;QACvE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACrB,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,IAAmB,EAAE,MAAe,EAAQ,EAAE;QAC3D,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACrC,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxD,IAAI,CAAC,CAAC,SAAS,IAAI,aAAa,CAAC;oBAAE,SAAS;gBAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;oBAAE,SAAS;gBAClF,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAS;gBAC9C,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAE,CAAC;gBACzC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,MAAM,EAAE,CAAC,CAAC;gBAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ;YAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACzD,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAElB,OAAO;QACL,QAAQ;QACR,OAAO;QACP,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;YAC7C,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC;QAClE,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/codegen/styles.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAsB,MAAM,kBAAkB,CAAC"}
@@ -2,10 +2,13 @@ import { type JpatchOp, type RenderDomNode } from '../types.js';
2
2
  /**
3
3
  * Apply RenderNode ops to one page tree. Ops whose target is not in this tree
4
4
  * are ignored (they belong to another page) and returned in `skipped` so the
5
- * caller can route them; nothing is dropped silently.
5
+ * caller can route them; nothing is dropped silently. `warnings` carries
6
+ * CHILDREN_REBASED when a directive resolved differently from its literal
7
+ * intent, exactly when the server flags it.
6
8
  */
7
9
  export declare function applyNodeOps(root: RenderDomNode | null, ops: JpatchOp[]): {
8
10
  root: RenderDomNode | null;
9
11
  skipped: JpatchOp[];
10
12
  orphans: Map<string, RenderDomNode>;
13
+ warnings: string[];
11
14
  };
@@ -1,6 +1,7 @@
1
1
  // Apply RenderNode ops to a page tree (the pull direction). The inverse of
2
2
  // diffTree: applyNodeOps(base, diffTree(base, x)) ≡ x.
3
3
  import { sidecarFilled, sidecarOf, } from '../types.js';
4
+ import { resolveChildOrder } from './childrenOrder.js';
4
5
  import { applyMergePatch } from './mergePatch.js';
5
6
  function buildState(root) {
6
7
  const index = new Map();
@@ -20,13 +21,16 @@ function buildState(root) {
20
21
  /**
21
22
  * Apply RenderNode ops to one page tree. Ops whose target is not in this tree
22
23
  * are ignored (they belong to another page) and returned in `skipped` so the
23
- * caller can route them; nothing is dropped silently.
24
+ * caller can route them; nothing is dropped silently. `warnings` carries
25
+ * CHILDREN_REBASED when a directive resolved differently from its literal
26
+ * intent, exactly when the server flags it.
24
27
  */
25
28
  export function applyNodeOps(root, ops) {
26
29
  const state = buildState(root);
27
30
  const skipped = [];
28
31
  // Created-but-not-yet-linked nodes park here until a children directive links them.
29
32
  const orphans = new Map();
33
+ let rebased = false;
30
34
  for (const op of ops) {
31
35
  if (op.entity !== 'RenderNode') {
32
36
  skipped.push(op);
@@ -114,8 +118,8 @@ export function applyNodeOps(root, ops) {
114
118
  else
115
119
  delete node.actionProps;
116
120
  }
117
- if (op.children) {
118
- applyChildrenDirective(state, node, op.children, orphans);
121
+ if (op.children && applyChildrenDirective(state, node, op.children, orphans)) {
122
+ rebased = true;
119
123
  }
120
124
  }
121
125
  // Root replacement: the old root was deleted and a new tree created with no
@@ -127,39 +131,47 @@ export function applyNodeOps(root, ops) {
127
131
  orphans.clear();
128
132
  }
129
133
  }
130
- return { root: state.root, skipped, orphans };
134
+ return { root: state.root, skipped, orphans, warnings: rebased ? ['CHILDREN_REBASED'] : [] };
131
135
  }
136
+ /**
137
+ * Resolve a children directive the way the server does (RFC-0001 §5.2,
138
+ * service--mapplesorg #724/#725): order via resolveChildOrder, then every ref
139
+ * must resolve in this tree and must not be the target or one of its
140
+ * ancestors — such a ref is skipped. A ref linked elsewhere is reparented; a
141
+ * child left out parks in `orphans`. Returns whether the result was rebased.
142
+ */
132
143
  function applyChildrenDirective(state, node, directive, orphans) {
133
- if (directive.remove) {
134
- for (const ref of directive.remove) {
135
- const removed = node.children.find((c) => c.sid === ref);
136
- node.children = node.children.filter((c) => c.sid !== ref);
137
- if (removed) {
138
- state.parents.delete(ref);
139
- orphans.set(ref, removed); // may be re-linked under a new parent
140
- }
141
- }
144
+ const current = node.children.map((c) => c.sid);
145
+ const resolved = resolveChildOrder(current, directive);
146
+ let rebased = resolved.rebased;
147
+ const lineage = new Set();
148
+ for (let sid = node.sid; sid !== undefined; sid = state.parents.get(sid)) {
149
+ lineage.add(sid);
142
150
  }
143
- if (directive.insert) {
144
- for (const ins of directive.insert) {
145
- const child = state.index.get(ins.ref) ?? orphans.get(ins.ref);
146
- if (!child)
147
- throw new Error(`children.insert references unknown node ${ins.ref}`);
148
- orphans.delete(ins.ref);
149
- const at = Math.max(0, Math.min(ins.at, node.children.length));
150
- node.children.splice(at, 0, child);
151
- state.parents.set(ins.ref, node.sid);
151
+ const kept = [];
152
+ for (const sid of resolved.order) {
153
+ const child = state.index.get(sid) ?? orphans.get(sid);
154
+ if (!child || lineage.has(sid)) {
155
+ rebased = true;
156
+ continue;
157
+ }
158
+ if (!current.includes(sid)) {
159
+ const oldParent = state.parents.get(sid);
160
+ const parent = oldParent === undefined ? undefined : state.index.get(oldParent);
161
+ if (parent)
162
+ parent.children = parent.children.filter((c) => c.sid !== sid);
163
+ orphans.delete(sid);
152
164
  }
165
+ state.parents.set(sid, node.sid);
166
+ kept.push(child);
153
167
  }
154
- if (directive.move) {
155
- for (const mv of directive.move) {
156
- const from = node.children.findIndex((c) => c.sid === mv.ref);
157
- if (from === -1)
158
- continue; // clamped server-side; mirror the tolerance
159
- const [child] = node.children.splice(from, 1);
160
- const to = Math.max(0, Math.min(mv.to, node.children.length));
161
- node.children.splice(to, 0, child);
168
+ for (const child of node.children) {
169
+ if (!kept.includes(child)) {
170
+ state.parents.delete(child.sid);
171
+ orphans.set(child.sid, child); // may be re-linked under a new parent
162
172
  }
163
173
  }
174
+ node.children = kept;
175
+ return rebased;
164
176
  }
165
177
  //# sourceMappingURL=applyOps.js.map