@kernlang/react 2.0.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.
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Shared utilities for building multi-file artifacts from structure plans.
3
+ *
4
+ * Used by all 3 React transpilers (Tailwind, Next.js, Web) when
5
+ * structure !== 'flat' to convert a StructurePlan into GeneratedArtifact[].
6
+ */
7
+ import type { GeneratedArtifact, IRNode, ResolvedKernConfig } from '@kernlang/core';
8
+ import type { StructurePlan, PlannedFile } from './structure.js';
9
+ export interface StructuredResult {
10
+ entryCode: string;
11
+ artifacts: GeneratedArtifact[];
12
+ }
13
+ /**
14
+ * Build artifacts from a structure plan.
15
+ *
16
+ * @param plan - The structure plan from planStructure()
17
+ * @param renderFile - Callback to render a single file's nodes to code string.
18
+ * Receives the planned file, and returns the rendered code for that file.
19
+ * @param root - The root IR node
20
+ * @param config - Resolved config
21
+ */
22
+ export declare function buildStructuredArtifacts(plan: StructurePlan, renderFile: (file: PlannedFile, config: ResolvedKernConfig) => string, root: IRNode, config: ResolvedKernConfig): StructuredResult;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Shared utilities for building multi-file artifacts from structure plans.
3
+ *
4
+ * Used by all 3 React transpilers (Tailwind, Next.js, Web) when
5
+ * structure !== 'flat' to convert a StructurePlan into GeneratedArtifact[].
6
+ */
7
+ import { extractHooks, generateStateHookCode, generateLogicHookCode, generateTypesCode, generateBarrelCode, } from './structure.js';
8
+ /**
9
+ * Build artifacts from a structure plan.
10
+ *
11
+ * @param plan - The structure plan from planStructure()
12
+ * @param renderFile - Callback to render a single file's nodes to code string.
13
+ * Receives the planned file, and returns the rendered code for that file.
14
+ * @param root - The root IR node
15
+ * @param config - Resolved config
16
+ */
17
+ export function buildStructuredArtifacts(plan, renderFile, root, config) {
18
+ const featureName = root.props?.name || 'Component';
19
+ const artifacts = [];
20
+ let entryCode = '';
21
+ // Collect state and logic nodes from root children
22
+ const stateNodes = [];
23
+ const logicNodes = [];
24
+ for (const child of root.children || []) {
25
+ if (child.type === 'state')
26
+ stateNodes.push(child);
27
+ if (child.type === 'logic' || child.type === 'handler')
28
+ logicNodes.push(child);
29
+ }
30
+ // Determine hooks directory from plan
31
+ const hookFiles = plan.files.filter(f => f.artifactType === 'hook');
32
+ const hooksDir = hookFiles.length > 0
33
+ ? hookFiles[0].path.substring(0, hookFiles[0].path.lastIndexOf('/'))
34
+ : 'hooks';
35
+ const hooks = extractHooks(featureName, stateNodes, logicNodes, hooksDir);
36
+ for (const file of plan.files) {
37
+ if (file.artifactType === 'hook') {
38
+ // Generate hook code
39
+ const matchingHook = hooks.find(h => h.path === file.path);
40
+ if (matchingHook) {
41
+ const code = matchingHook.stateDecls.length > 0
42
+ ? generateStateHookCode(matchingHook)
43
+ : generateLogicHookCode(matchingHook, hooks.find(h => h.stateDecls.length > 0)?.hookName);
44
+ artifacts.push({ path: file.path, content: code, type: 'hook' });
45
+ }
46
+ continue;
47
+ }
48
+ if (file.artifactType === 'types') {
49
+ const stateDecls = stateNodes.map(n => ({
50
+ name: n.props?.name || 'value',
51
+ initial: String(n.props?.initial ?? ''),
52
+ }));
53
+ const code = generateTypesCode(featureName, stateDecls);
54
+ artifacts.push({ path: file.path, content: code, type: 'types' });
55
+ continue;
56
+ }
57
+ if (file.artifactType === 'theme') {
58
+ // Theme nodes are meta — just export the theme object
59
+ const themeNodes = file.nodes;
60
+ const themeLines = [];
61
+ for (const tn of themeNodes) {
62
+ const name = tn.props?.name || 'theme';
63
+ const styles = tn.props?.styles || {};
64
+ themeLines.push(`export const ${name} = ${JSON.stringify(styles, null, 2)};`);
65
+ }
66
+ artifacts.push({ path: file.path, content: themeLines.join('\n\n'), type: 'theme' });
67
+ continue;
68
+ }
69
+ // Render component/entry/page/template files
70
+ const code = renderFile(file, config);
71
+ if (file.isEntry) {
72
+ entryCode = code;
73
+ // Also add as artifact so CLI can write it to the correct path
74
+ artifacts.push({ path: file.path, content: code, type: file.artifactType });
75
+ }
76
+ else {
77
+ artifacts.push({ path: file.path, content: code, type: file.artifactType });
78
+ }
79
+ }
80
+ // Barrel exports
81
+ for (const barrel of plan.barrels) {
82
+ const code = generateBarrelCode(barrel);
83
+ artifacts.push({ path: barrel.path, content: code, type: 'barrel' });
84
+ }
85
+ return { entryCode, artifacts };
86
+ }
87
+ //# sourceMappingURL=artifact-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-utils.js","sourceRoot":"","sources":["../src/artifact-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * React-specific codegen — generates JSX/TSX code for provider and effect nodes.
3
+ *
4
+ * These nodes live in @kernlang/react because they produce JSX output,
5
+ * unlike hook which generates pure TypeScript and lives in @kernlang/core.
6
+ */
7
+ import type { IRNode } from '@kernlang/core';
8
+ export declare function generateProvider(node: IRNode): string[];
9
+ export declare function generateEffect(node: IRNode): string[];
10
+ /** Check if a node is a React codegen node (provider or top-level effect). */
11
+ export declare function isReactNode(type: string): boolean;
12
+ /** Generate TSX for a React codegen node. */
13
+ export declare function generateReactNode(node: IRNode): string[];
@@ -0,0 +1,188 @@
1
+ /**
2
+ * React-specific codegen — generates JSX/TSX code for provider and effect nodes.
3
+ *
4
+ * These nodes live in @kernlang/react because they produce JSX output,
5
+ * unlike hook which generates pure TypeScript and lives in @kernlang/core.
6
+ */
7
+ // ── Helpers ──────────────────────────────────────────────────────────────
8
+ function p(node) {
9
+ return node.props || {};
10
+ }
11
+ function kids(node, type) {
12
+ const c = node.children || [];
13
+ return type ? c.filter(n => n.type === type) : c;
14
+ }
15
+ function firstChild(node, type) {
16
+ return kids(node, type)[0];
17
+ }
18
+ function dedent(code) {
19
+ const lines = code.split('\n');
20
+ const nonEmpty = lines.filter(l => l.trim().length > 0);
21
+ if (nonEmpty.length === 0)
22
+ return code;
23
+ const min = Math.min(...nonEmpty.map(l => l.match(/^(\s*)/)?.[1].length ?? 0));
24
+ return lines.map(l => l.slice(min)).join('\n');
25
+ }
26
+ function handlerCode(node) {
27
+ const handler = firstChild(node, 'handler');
28
+ if (!handler)
29
+ return '';
30
+ const raw = p(handler).code || '';
31
+ return dedent(raw);
32
+ }
33
+ // ── Provider ─────────────────────────────────────────────────────────────
34
+ // provider name=Search type=UseSearchResult
35
+ // prop name=initialQuery type=string
36
+ // prop name=category type=string optional=true
37
+ // handler <<<
38
+ // const value = useSearch({ query: initialQuery, category });
39
+ // >>>
40
+ //
41
+ // Generates 3 pieces:
42
+ // 1. SearchContext = createContext<UseSearchResult | null>(null)
43
+ // 2. SearchProvider component with props + <SearchContext.Provider>
44
+ // 3. useSearchContext() consumer hook with null-check
45
+ export function generateProvider(node) {
46
+ const props = p(node);
47
+ const name = props.name;
48
+ const valueType = props.type;
49
+ const lines = [];
50
+ lines.push("'use client';");
51
+ lines.push('');
52
+ lines.push("import { createContext, useContext } from 'react';");
53
+ lines.push(`import type { ReactNode } from 'react';`);
54
+ lines.push('');
55
+ // 1. Context
56
+ lines.push(`const ${name}Context = createContext<${valueType} | null>(null);`);
57
+ lines.push('');
58
+ // 2. Props interface
59
+ const propNodes = kids(node, 'prop');
60
+ lines.push(`export interface ${name}ProviderProps {`);
61
+ lines.push(` children: ReactNode;`);
62
+ for (const prop of propNodes) {
63
+ const pp = p(prop);
64
+ const opt = pp.optional === 'true' || pp.optional === true ? '?' : '';
65
+ lines.push(` ${pp.name}${opt}: ${pp.type};`);
66
+ }
67
+ lines.push('}');
68
+ lines.push('');
69
+ // 3. Provider component
70
+ const propNames = propNodes.map(pn => p(pn).name);
71
+ const destructured = ['children', ...propNames].join(', ');
72
+ lines.push(`export function ${name}Provider({ ${destructured} }: ${name}ProviderProps) {`);
73
+ const code = handlerCode(node);
74
+ if (code) {
75
+ for (const line of code.split('\n')) {
76
+ lines.push(` ${line}`);
77
+ }
78
+ }
79
+ lines.push('');
80
+ lines.push(` return (`);
81
+ lines.push(` <${name}Context.Provider value={value}>`);
82
+ lines.push(` {children}`);
83
+ lines.push(` </${name}Context.Provider>`);
84
+ lines.push(` );`);
85
+ lines.push('}');
86
+ lines.push('');
87
+ // 4. Consumer hook
88
+ lines.push(`export function use${name}Context(): ${valueType} {`);
89
+ lines.push(` const ctx = useContext(${name}Context);`);
90
+ lines.push(` if (ctx === null) {`);
91
+ lines.push(` throw new Error('use${name}Context must be used within a ${name}Provider');`);
92
+ lines.push(` }`);
93
+ lines.push(` return ctx;`);
94
+ lines.push('}');
95
+ return lines;
96
+ }
97
+ // ── Effect (Component) ──────────────────────────────────────────────────
98
+ // effect name=TrackingContainer generic=T once=true
99
+ // prop name=entities type="T[]"
100
+ // prop name=generator type="(items: T[]) => Promise<TrackingEvent>"
101
+ // deps="entities,generator"
102
+ // handler <<<
103
+ // generator(entities).then(event => trackPageLoadEvent(event));
104
+ // >>>
105
+ // cleanup <<<
106
+ // abortCtrl.abort();
107
+ // >>>
108
+ //
109
+ // Generates: props interface + component with useRef guard (once=true) +
110
+ // useEffect with deps + optional cleanup + return null
111
+ export function generateEffect(node) {
112
+ const props = p(node);
113
+ const name = props.name;
114
+ const generic = props.generic;
115
+ const once = props.once === 'true' || props.once === true;
116
+ const deps = props.deps || '';
117
+ const lines = [];
118
+ const reactImports = ['useEffect'];
119
+ if (once)
120
+ reactImports.push('useRef');
121
+ lines.push("'use client';");
122
+ lines.push('');
123
+ lines.push(`import { ${reactImports.sort().join(', ')} } from 'react';`);
124
+ lines.push('');
125
+ // Generic type parameter
126
+ const genericParam = generic ? `<${generic}>` : '';
127
+ const genericConstraint = generic ? `<${generic}>` : '';
128
+ // Props interface
129
+ const propNodes = kids(node, 'prop');
130
+ lines.push(`export interface ${name}Props${genericParam} {`);
131
+ for (const prop of propNodes) {
132
+ const pp = p(prop);
133
+ const opt = pp.optional === 'true' || pp.optional === true ? '?' : '';
134
+ lines.push(` ${pp.name}${opt}: ${pp.type};`);
135
+ }
136
+ lines.push('}');
137
+ lines.push('');
138
+ // Component
139
+ const propNames = propNodes.map(pn => p(pn).name);
140
+ const destructured = propNames.join(', ');
141
+ lines.push(`export function ${name}${genericConstraint}({ ${destructured} }: ${name}Props${genericConstraint}) {`);
142
+ // Once guard — useRef for React 18 Strict Mode double-mount safety
143
+ if (once) {
144
+ lines.push(` const hasRun = useRef(false);`);
145
+ }
146
+ // useEffect
147
+ const depsArr = deps ? `[${deps}]` : '[]';
148
+ lines.push(` useEffect(() => {`);
149
+ if (once) {
150
+ lines.push(` if (hasRun.current) return;`);
151
+ lines.push(` hasRun.current = true;`);
152
+ }
153
+ const code = handlerCode(node);
154
+ if (code) {
155
+ for (const line of code.split('\n')) {
156
+ lines.push(` ${line}`);
157
+ }
158
+ }
159
+ // Cleanup
160
+ const cleanupNode = firstChild(node, 'cleanup');
161
+ if (cleanupNode) {
162
+ const cleanupCode = p(cleanupNode).code || '';
163
+ const cleanupDedented = dedent(cleanupCode);
164
+ lines.push(` return () => {`);
165
+ for (const line of cleanupDedented.split('\n')) {
166
+ lines.push(` ${line}`);
167
+ }
168
+ lines.push(` };`);
169
+ }
170
+ lines.push(` }, ${depsArr});`);
171
+ lines.push('');
172
+ lines.push(` return null;`);
173
+ lines.push('}');
174
+ return lines;
175
+ }
176
+ /** Check if a node is a React codegen node (provider or top-level effect). */
177
+ export function isReactNode(type) {
178
+ return type === 'provider' || type === 'effect';
179
+ }
180
+ /** Generate TSX for a React codegen node. */
181
+ export function generateReactNode(node) {
182
+ switch (node.type) {
183
+ case 'provider': return generateProvider(node);
184
+ case 'effect': return generateEffect(node);
185
+ default: return [];
186
+ }
187
+ }
188
+ //# sourceMappingURL=codegen-react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen-react.js","sourceRoot":"","sources":["../src/codegen-react.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @kernlang/react — React transpilers (Tailwind, Next.js, Web) + React codegen
3
+ */
4
+ export { transpileTailwind } from './transpiler-tailwind.js';
5
+ export { transpileNextjs } from './transpiler-nextjs.js';
6
+ export { transpileWeb } from './transpiler-web.js';
7
+ export { planStructure, classifyNode } from './structure.js';
8
+ export type { StructurePlan, PlannedFile, NodeRole, ExtractedHook } from './structure.js';
9
+ export { buildStructuredArtifacts } from './artifact-utils.js';
10
+ export { generateProvider, generateEffect, generateReactNode, isReactNode } from './codegen-react.js';
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @kernlang/react — React transpilers (Tailwind, Next.js, Web) + React codegen
3
+ */
4
+ export { transpileTailwind } from './transpiler-tailwind.js';
5
+ export { transpileNextjs } from './transpiler-nextjs.js';
6
+ export { transpileWeb } from './transpiler-web.js';
7
+ export { planStructure, classifyNode } from './structure.js';
8
+ export { buildStructuredArtifacts } from './artifact-utils.js';
9
+ export { generateProvider, generateEffect, generateReactNode, isReactNode } from './codegen-react.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * KERN Structure Planner
3
+ *
4
+ * Target-agnostic module that splits an IRNode tree into multiple files
5
+ * based on a structure pattern (bulletproof, atomic, kern, flat).
6
+ *
7
+ * The planner classifies nodes by role, assigns them to files with correct
8
+ * paths per pattern, extracts hooks (state/logic), and resolves imports.
9
+ */
10
+ import type { IRNode, GeneratedArtifact, ResolvedKernConfig } from '@kernlang/core';
11
+ export type NodeRole = 'surface' | 'block' | 'element' | 'container' | 'state' | 'logic' | 'theme' | 'meta';
12
+ export interface PlannedFile {
13
+ path: string;
14
+ artifactType: GeneratedArtifact['type'];
15
+ nodes: IRNode[];
16
+ rootNode: IRNode;
17
+ dependsOn: string[];
18
+ isEntry: boolean;
19
+ componentName?: string;
20
+ }
21
+ export interface StructurePlan {
22
+ files: PlannedFile[];
23
+ barrels: BarrelExport[];
24
+ }
25
+ export interface BarrelExport {
26
+ path: string;
27
+ exports: {
28
+ name: string;
29
+ from: string;
30
+ }[];
31
+ }
32
+ export interface ExtractedHook {
33
+ hookName: string;
34
+ path: string;
35
+ stateDecls: {
36
+ name: string;
37
+ initial: string;
38
+ }[];
39
+ logicBlocks: string[];
40
+ returnedValues: string[];
41
+ importedBy: string[];
42
+ }
43
+ export declare function classifyNode(node: IRNode): NodeRole;
44
+ export declare function extractHooks(featureName: string, stateNodes: IRNode[], logicNodes: IRNode[], hooksDir: string): ExtractedHook[];
45
+ export declare function generateStateHookCode(hook: ExtractedHook): string;
46
+ export declare function generateLogicHookCode(hook: ExtractedHook, stateHookName?: string): string;
47
+ export declare function generateTypesCode(featureName: string, stateDecls: {
48
+ name: string;
49
+ initial: string;
50
+ }[]): string;
51
+ export declare function generateBarrelCode(barrel: BarrelExport): string;
52
+ export declare function adaptPlanForNextjs(plan: StructurePlan, root: IRNode): StructurePlan;
53
+ export declare function planStructure(root: IRNode, config: ResolvedKernConfig): StructurePlan | null;