@creact-labs/creact 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 (103) hide show
  1. package/LICENSE +212 -0
  2. package/README.md +379 -0
  3. package/dist/cli/commands/BuildCommand.d.ts +40 -0
  4. package/dist/cli/commands/BuildCommand.js +151 -0
  5. package/dist/cli/commands/DeployCommand.d.ts +38 -0
  6. package/dist/cli/commands/DeployCommand.js +194 -0
  7. package/dist/cli/commands/DevCommand.d.ts +52 -0
  8. package/dist/cli/commands/DevCommand.js +385 -0
  9. package/dist/cli/commands/PlanCommand.d.ts +39 -0
  10. package/dist/cli/commands/PlanCommand.js +164 -0
  11. package/dist/cli/commands/index.d.ts +36 -0
  12. package/dist/cli/commands/index.js +43 -0
  13. package/dist/cli/core/ArgumentParser.d.ts +46 -0
  14. package/dist/cli/core/ArgumentParser.js +127 -0
  15. package/dist/cli/core/BaseCommand.d.ts +75 -0
  16. package/dist/cli/core/BaseCommand.js +95 -0
  17. package/dist/cli/core/CLIContext.d.ts +68 -0
  18. package/dist/cli/core/CLIContext.js +183 -0
  19. package/dist/cli/core/CommandRegistry.d.ts +64 -0
  20. package/dist/cli/core/CommandRegistry.js +89 -0
  21. package/dist/cli/core/index.d.ts +36 -0
  22. package/dist/cli/core/index.js +43 -0
  23. package/dist/cli/index.d.ts +35 -0
  24. package/dist/cli/index.js +100 -0
  25. package/dist/cli/output.d.ts +204 -0
  26. package/dist/cli/output.js +437 -0
  27. package/dist/cli/utils.d.ts +59 -0
  28. package/dist/cli/utils.js +76 -0
  29. package/dist/context/createContext.d.ts +90 -0
  30. package/dist/context/createContext.js +113 -0
  31. package/dist/context/index.d.ts +30 -0
  32. package/dist/context/index.js +35 -0
  33. package/dist/core/CReact.d.ts +409 -0
  34. package/dist/core/CReact.js +1127 -0
  35. package/dist/core/CloudDOMBuilder.d.ts +429 -0
  36. package/dist/core/CloudDOMBuilder.js +1198 -0
  37. package/dist/core/ContextDependencyTracker.d.ts +165 -0
  38. package/dist/core/ContextDependencyTracker.js +448 -0
  39. package/dist/core/ErrorRecoveryManager.d.ts +145 -0
  40. package/dist/core/ErrorRecoveryManager.js +443 -0
  41. package/dist/core/EventBus.d.ts +91 -0
  42. package/dist/core/EventBus.js +185 -0
  43. package/dist/core/ProviderOutputTracker.d.ts +211 -0
  44. package/dist/core/ProviderOutputTracker.js +476 -0
  45. package/dist/core/ReactiveUpdateQueue.d.ts +76 -0
  46. package/dist/core/ReactiveUpdateQueue.js +121 -0
  47. package/dist/core/Reconciler.d.ts +415 -0
  48. package/dist/core/Reconciler.js +1037 -0
  49. package/dist/core/RenderScheduler.d.ts +153 -0
  50. package/dist/core/RenderScheduler.js +519 -0
  51. package/dist/core/Renderer.d.ts +276 -0
  52. package/dist/core/Renderer.js +791 -0
  53. package/dist/core/Runtime.d.ts +246 -0
  54. package/dist/core/Runtime.js +640 -0
  55. package/dist/core/StateBindingManager.d.ts +121 -0
  56. package/dist/core/StateBindingManager.js +309 -0
  57. package/dist/core/StateMachine.d.ts +424 -0
  58. package/dist/core/StateMachine.js +787 -0
  59. package/dist/core/StructuralChangeDetector.d.ts +140 -0
  60. package/dist/core/StructuralChangeDetector.js +363 -0
  61. package/dist/core/Validator.d.ts +127 -0
  62. package/dist/core/Validator.js +279 -0
  63. package/dist/core/errors.d.ts +153 -0
  64. package/dist/core/errors.js +202 -0
  65. package/dist/core/index.d.ts +38 -0
  66. package/dist/core/index.js +64 -0
  67. package/dist/core/types.d.ts +263 -0
  68. package/dist/core/types.js +48 -0
  69. package/dist/hooks/context.d.ts +147 -0
  70. package/dist/hooks/context.js +334 -0
  71. package/dist/hooks/useContext.d.ts +113 -0
  72. package/dist/hooks/useContext.js +169 -0
  73. package/dist/hooks/useEffect.d.ts +105 -0
  74. package/dist/hooks/useEffect.js +540 -0
  75. package/dist/hooks/useInstance.d.ts +139 -0
  76. package/dist/hooks/useInstance.js +441 -0
  77. package/dist/hooks/useState.d.ts +120 -0
  78. package/dist/hooks/useState.js +298 -0
  79. package/dist/index.d.ts +46 -0
  80. package/dist/index.js +70 -0
  81. package/dist/jsx.d.ts +64 -0
  82. package/dist/jsx.js +76 -0
  83. package/dist/providers/DummyBackendProvider.d.ts +193 -0
  84. package/dist/providers/DummyBackendProvider.js +189 -0
  85. package/dist/providers/DummyCloudProvider.d.ts +128 -0
  86. package/dist/providers/DummyCloudProvider.js +157 -0
  87. package/dist/providers/IBackendProvider.d.ts +177 -0
  88. package/dist/providers/IBackendProvider.js +31 -0
  89. package/dist/providers/ICloudProvider.d.ts +146 -0
  90. package/dist/providers/ICloudProvider.js +31 -0
  91. package/dist/providers/index.d.ts +31 -0
  92. package/dist/providers/index.js +31 -0
  93. package/dist/test-event-callbacks.d.ts +0 -0
  94. package/dist/test-event-callbacks.js +1 -0
  95. package/dist/utils/Logger.d.ts +144 -0
  96. package/dist/utils/Logger.js +220 -0
  97. package/dist/utils/Output.d.ts +161 -0
  98. package/dist/utils/Output.js +401 -0
  99. package/dist/utils/deepEqual.d.ts +71 -0
  100. package/dist/utils/deepEqual.js +276 -0
  101. package/dist/utils/naming.d.ts +241 -0
  102. package/dist/utils/naming.js +376 -0
  103. package/package.json +87 -0
@@ -0,0 +1,415 @@
1
+ /**
2
+
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+
5
+ * you may not use this file except in compliance with the License.
6
+
7
+ * You may obtain a copy of the License at
8
+
9
+ *
10
+
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ *
14
+
15
+ * Unless required by applicable law or agreed to in writing, software
16
+
17
+ * distributed under the License is distributed on an "AS IS" BASIS,
18
+
19
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+
21
+ * See the License for the specific language governing permissions and
22
+
23
+ * limitations under the License.
24
+
25
+ *
26
+
27
+ * Copyright 2025 Daniel Coutinho Ribeiro
28
+
29
+ */
30
+ import { CloudDOMNode } from './types';
31
+ /**
32
+ * Type representing a construct (function, class, or string)
33
+ */
34
+ export type ConstructLike = {
35
+ name?: string;
36
+ } | Function | string;
37
+ /**
38
+ * ChangeSet represents the minimal set of operations to reconcile two CloudDOM states
39
+ *
40
+ * REQ-O01: State Machine needs diff to detect changes
41
+ * REQ-O04: Plan Command needs diff to show preview
42
+ */
43
+ export interface ChangeSet {
44
+ /** Nodes that exist in current but not in previous (need to be created) */
45
+ creates: CloudDOMNode[];
46
+ /** Nodes that exist in both but have different props (need to be updated) */
47
+ updates: CloudDOMNode[];
48
+ /** Nodes that exist in previous but not in current (need to be deleted) */
49
+ deletes: CloudDOMNode[];
50
+ /** Nodes that changed type (need to be replaced: delete + create) */
51
+ replacements: CloudDOMNode[];
52
+ /** Nodes that moved in the hierarchy (includes node ID for traceability) */
53
+ moves: Array<{
54
+ nodeId: string;
55
+ from: string;
56
+ to: string;
57
+ }>;
58
+ /** Deployment order based on dependency graph (topologically sorted) */
59
+ deploymentOrder: string[];
60
+ /** Parallel deployment batches (nodes at same depth can deploy in parallel) */
61
+ parallelBatches: string[][];
62
+ }
63
+ /**
64
+ * Helper function to get total number of changes from a ChangeSet
65
+ * Single source of truth for change counting
66
+ */
67
+ export declare function getTotalChanges(changeSet: ChangeSet): number;
68
+ /**
69
+ * Helper function to check if a ChangeSet has any changes
70
+ */
71
+ export declare function hasChanges(changeSet: ChangeSet): boolean;
72
+ /**
73
+ * DependencyGraph represents resource dependencies for deployment ordering
74
+ *
75
+ * Maps node ID → array of dependency IDs
76
+ */
77
+ export interface DependencyGraph {
78
+ /** Adjacency list: node ID → dependency IDs */
79
+ dependencies: Map<string, string[]>;
80
+ /** Reverse adjacency list: node ID → dependent IDs (nodes that depend on this node) */
81
+ dependents: Map<string, string[]>;
82
+ }
83
+ /**
84
+ * Reconciler computes minimal change sets between CloudDOM states
85
+ *
86
+ * This is CReact's equivalent to React's Fiber reconciliation algorithm.
87
+ * It enables:
88
+ * - Incremental updates (only deploy what changed)
89
+ * - Plan preview (show diff before deploy)
90
+ * - Hot reload (apply deltas without full rebuild)
91
+ * - Dependency-aware ordering (deploy in correct order)
92
+ *
93
+ * REQ-O01: CloudDOM State Machine
94
+ * REQ-O04: Plan and Change Preview
95
+ */
96
+ export declare class Reconciler {
97
+ /**
98
+ * Internal methods exposed for testing
99
+ *
100
+ * These are pure functions that are ideal for unit testing.
101
+ * Prefixed with __ to indicate they're internal/testing-only.
102
+ */
103
+ __testing__: {
104
+ buildDependencyGraph: (nodes: CloudDOMNode[]) => DependencyGraph;
105
+ detectChangeType: (previous: CloudDOMNode, current: CloudDOMNode) => "replacement" | "update" | "none";
106
+ computeParallelBatches: (deploymentOrder: string[], graph: DependencyGraph) => string[][];
107
+ topologicalSort: (graph: DependencyGraph) => string[];
108
+ extractDependencies: (node: CloudDOMNode, nodeIds: Set<string>) => string[];
109
+ detectMoves: (previousMap: Map<string, CloudDOMNode>, currentMap: Map<string, CloudDOMNode>) => Array<{
110
+ nodeId: string;
111
+ from: string;
112
+ to: string;
113
+ }>;
114
+ validateGraph: (graph: DependencyGraph) => void;
115
+ computeShallowHash: (props: Record<string, any>) => string;
116
+ isMetadataKey: (key: string) => boolean;
117
+ };
118
+ /**
119
+ * Generate a human-readable diff visualization for UI/CLI
120
+ *
121
+ * Formats the ChangeSet as JSON suitable for:
122
+ * - CLI diff previews (like Terraform plans)
123
+ * - Web UI diff visualization
124
+ * - CI/CD pipeline reports
125
+ *
126
+ * @param changeSet - ChangeSet to visualize
127
+ * @returns JSON-serializable diff visualization
128
+ */
129
+ generateDiffVisualization(changeSet: ChangeSet): {
130
+ summary: {
131
+ creates: number;
132
+ updates: number;
133
+ deletes: number;
134
+ replacements: number;
135
+ moves: number;
136
+ total: number;
137
+ };
138
+ changes: Array<{
139
+ type: 'create' | 'update' | 'delete' | 'replacement' | 'move';
140
+ nodeId: string;
141
+ details?: any;
142
+ }>;
143
+ deployment: {
144
+ order: string[];
145
+ batches: Array<{
146
+ depth: number;
147
+ nodes: string[];
148
+ parallelism: number;
149
+ }>;
150
+ };
151
+ };
152
+ /**
153
+ * Debug logging helper
154
+ * Logs messages when CREACT_DEBUG environment variable is set
155
+ *
156
+ * Supports both string messages and structured data for telemetry.
157
+ * Includes timestamps for async reconciliation tracing.
158
+ */
159
+ private log;
160
+ /**
161
+ * Check if a key is internal metadata (starts with underscore)
162
+ *
163
+ * Used for filtering metadata from prop comparisons and dependency scanning.
164
+ *
165
+ * @param key - Property key to check
166
+ * @returns True if key is metadata
167
+ */
168
+ private isMetadataKey;
169
+ /**
170
+ * Compute a shallow hash of props for fast equality checks
171
+ *
172
+ * Creates a stable, key-order-independent hash by:
173
+ * - Filtering out special props (metadata, key, children)
174
+ * - Sorting entries by key
175
+ * - JSON stringifying the result
176
+ *
177
+ * This enables O(1) prop comparisons for unchanged nodes.
178
+ *
179
+ * @param props - Props object to hash
180
+ * @returns Stable hash string
181
+ */
182
+ private computeShallowHash;
183
+ /**
184
+ * Reconcile two CloudDOM states and compute minimal change set
185
+ *
186
+ * Algorithm:
187
+ * 1. Build ID maps for O(n) lookup
188
+ * 2. Detect creates (in current, not in previous)
189
+ * 3. Detect updates/replacements (in both, but props or construct changed)
190
+ * 4. Detect deletes (in previous, not in current)
191
+ * 5. Detect moves (nodes that changed parent)
192
+ * 6. Build dependency graph from current nodes
193
+ * 7. Compute topological sort for deployment order
194
+ * 8. Group independent resources into parallel batches
195
+ *
196
+ * Performance notes:
197
+ * - Synchronous for graphs <10k nodes
198
+ * - For larger graphs, consider async version with periodic yielding
199
+ * - Uses memoized deep equality for prop comparison
200
+ *
201
+ * REQ-O01: Diff algorithm for incremental updates
202
+ * REQ-O04: Change preview for plan command
203
+ *
204
+ * @param previous - Previous CloudDOM state
205
+ * @param current - Current CloudDOM state
206
+ * @returns ChangeSet with creates, updates, deletes, replacements, and deployment order
207
+ */
208
+ reconcile(previous: CloudDOMNode[], current: CloudDOMNode[]): ChangeSet;
209
+ /**
210
+ * Async reconcile for large CloudDOM graphs (>10k nodes)
211
+ *
212
+ * Yields periodically to prevent blocking the event loop.
213
+ * Useful for:
214
+ * - Large infrastructure graphs
215
+ * - UI responsiveness during diff computation
216
+ * - Long-running CI/CD pipelines
217
+ *
218
+ * Algorithm is identical to synchronous reconcile, but yields every N nodes.
219
+ *
220
+ * @param previous - Previous CloudDOM state
221
+ * @param current - Current CloudDOM state
222
+ * @param yieldInterval - Number of nodes to process before yielding (default: 1000)
223
+ * @returns Promise resolving to ChangeSet
224
+ */
225
+ reconcileAsync(previous: CloudDOMNode[], current: CloudDOMNode[], yieldInterval?: number): Promise<ChangeSet>;
226
+ /**
227
+ * Yield control to event loop
228
+ *
229
+ * Uses setImmediate in Node.js, setTimeout in browser.
230
+ * Prevents blocking during large graph reconciliation.
231
+ */
232
+ private yield;
233
+ /**
234
+ * Build a flat map of node ID → CloudDOMNode for O(n) lookup
235
+ *
236
+ * Recursively walks the CloudDOM tree and collects all nodes.
237
+ *
238
+ * @param nodes - CloudDOM tree (root nodes)
239
+ * @returns Map of node ID → CloudDOMNode
240
+ */
241
+ private buildNodeMap;
242
+ /**
243
+ * Detect moves (nodes that changed parent in hierarchy)
244
+ *
245
+ * A move is detected when:
246
+ * - Node exists in both previous and current
247
+ * - Node's parent path changed (using array equality, not string comparison)
248
+ *
249
+ * This is useful for hierarchical updates where resources move
250
+ * between parent containers.
251
+ *
252
+ * @param previousMap - Previous node map
253
+ * @param currentMap - Current node map
254
+ * @returns Array of move operations with node ID
255
+ */
256
+ private detectMoves;
257
+ /**
258
+ * Detect the type of change between two nodes
259
+ *
260
+ * Returns:
261
+ * - 'replacement': Construct type changed (needs delete + create)
262
+ * - 'update': Props changed but construct is same (can update in place)
263
+ * - 'none': No changes detected
264
+ *
265
+ * Performance optimization:
266
+ * - Uses shallow prop hashes for O(1) comparison
267
+ * - Only falls back to deep equality if hashes differ
268
+ * - Caches hashes in node metadata (_propHash)
269
+ *
270
+ * NOTE: The `state` field is intentionally NOT compared during reconciliation.
271
+ * Only `props` and `outputs` are compared. The `state` field contains useState
272
+ * values which should not trigger infrastructure updates. This separation ensures
273
+ * that application state changes don't cause unnecessary resource deployments.
274
+ *
275
+ * @param previous - Previous node
276
+ * @param current - Current node
277
+ * @returns Change type
278
+ */
279
+ private detectChangeType;
280
+ /**
281
+ * Check if two constructs are equal
282
+ *
283
+ * Constructs are considered equal if they have the same name.
284
+ * Handles edge cases like minified builds where function names may be undefined.
285
+ *
286
+ * NOTE: After serialization, construct field may be undefined, so we rely on
287
+ * constructType string field for comparison.
288
+ *
289
+ * @param a - First construct
290
+ * @param b - Second construct
291
+ * @returns True if constructs are equal
292
+ */
293
+ private constructsEqual;
294
+ /**
295
+ * Get the name of a construct
296
+ *
297
+ * @param construct - Construct to get name from
298
+ * @returns Construct name
299
+ */
300
+ private getConstructName;
301
+ /**
302
+ * Check if node props have changed using deep equality
303
+ *
304
+ * Compares props objects deeply to detect any changes.
305
+ * Uses the deepEqual utility with memoization for performance.
306
+ *
307
+ * Excludes special props that don't affect rendering:
308
+ * - Metadata props (starting with _)
309
+ * - key prop (used for identity, not rendering)
310
+ * - children prop (handled separately in rendering)
311
+ *
312
+ * @param prevProps - Previous props (optional, defaults to empty object)
313
+ * @param currProps - Current props (optional, defaults to empty object)
314
+ * @returns True if props have changed
315
+ */
316
+ private propsChanged;
317
+ /**
318
+ * Check if outputs have changed using deep equality
319
+ *
320
+ * Treats empty objects ({}) as equivalent to undefined for idempotency.
321
+ *
322
+ * NOTE: This method only receives and compares the `outputs` field from CloudDOMNode.
323
+ * The `state` field is never passed to this method, ensuring that useState values
324
+ * do not trigger infrastructure updates. This separation is automatic - callers
325
+ * explicitly pass `node.outputs`, not `node.state`.
326
+ *
327
+ * @param previous - Previous outputs (from node.outputs field only)
328
+ * @param current - Current outputs (from node.outputs field only)
329
+ * @returns True if outputs changed
330
+ */
331
+ private outputsChanged;
332
+ /**
333
+ * Build dependency graph from CloudDOM nodes
334
+ *
335
+ * Scans node props for references to other node IDs and builds
336
+ * an adjacency list representing dependencies.
337
+ *
338
+ * A node depends on another if its props reference the other node's ID.
339
+ *
340
+ * REQ-O01: Dependency graph for deployment ordering
341
+ *
342
+ * @param nodes - CloudDOM nodes
343
+ * @returns DependencyGraph with adjacency lists
344
+ */
345
+ private buildDependencyGraph;
346
+ /**
347
+ * Validate dependency graph integrity
348
+ *
349
+ * Ensures all dependencies exist in the graph and no missing node IDs remain.
350
+ *
351
+ * @param graph - Dependency graph to validate
352
+ * @throws ReconciliationError if graph is invalid
353
+ */
354
+ private validateGraph;
355
+ /**
356
+ * Extract dependencies from a node's props
357
+ *
358
+ * Recursively scans props object for strings that match other node IDs.
359
+ *
360
+ * Optimizations:
361
+ * - Skips props that start with underscore (internal metadata)
362
+ * - Uses explicit ref convention when available (props.ref or props.dependsOn)
363
+ * - Caches known non-ID props to avoid false positives
364
+ *
365
+ * @param node - CloudDOM node
366
+ * @param nodeIds - Set of all node IDs for validation
367
+ * @returns Array of dependency IDs
368
+ */
369
+ private extractDependencies;
370
+ /**
371
+ * Check if a prop key is known to never contain node IDs
372
+ *
373
+ * This helps avoid false positives in dependency extraction.
374
+ *
375
+ * @param key - Prop key
376
+ * @returns True if this prop is known to not contain IDs
377
+ */
378
+ private isKnownNonIdProp;
379
+ /**
380
+ * Detect circular dependencies using DFS
381
+ *
382
+ * Collects all cycles before throwing to provide comprehensive diagnostics.
383
+ *
384
+ * REQ-O01: Circular dependency detection
385
+ *
386
+ * @param dependencies - Dependency adjacency list
387
+ * @throws ReconciliationError if circular dependencies are detected
388
+ */
389
+ private detectCircularDependencies;
390
+ /**
391
+ * Compute topological sort for deployment order using Kahn's algorithm
392
+ *
393
+ * Returns array of node IDs in deployment order (dependencies first).
394
+ * Nodes with same depth are sorted by ID for determinism.
395
+ *
396
+ * REQ-O01: Topological sort for deployment order
397
+ *
398
+ * @param graph - Dependency graph
399
+ * @returns Array of node IDs in deployment order
400
+ */
401
+ private topologicalSort;
402
+ /**
403
+ * Compute parallel deployment batches
404
+ *
405
+ * Groups nodes by depth in dependency graph.
406
+ * Nodes at same depth can deploy in parallel (no dependencies between them).
407
+ *
408
+ * REQ-O01: Parallel deployment batches
409
+ *
410
+ * @param deploymentOrder - Topologically sorted node IDs
411
+ * @param graph - Dependency graph
412
+ * @returns Array of batches (each batch can deploy in parallel)
413
+ */
414
+ private computeParallelBatches;
415
+ }