@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,429 @@
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 { FiberNode, CloudDOMNode, OutputChange } from './types';
31
+ import { ICloudProvider } from '../providers/ICloudProvider';
32
+ import { StateBindingManager } from './StateBindingManager';
33
+ import { ProviderOutputTracker } from './ProviderOutputTracker';
34
+ /**
35
+ * CloudDOMBuilder transforms a Fiber tree into a CloudDOM tree
36
+ *
37
+ * The CloudDOM tree represents actual cloud resources to be deployed:
38
+ * - Only includes components that called useInstance (have cloudDOMNode attached)
39
+ * - Filters out container components (no useInstance)
40
+ * - Builds parent-child relationships for deployment order
41
+ * - Generates resource IDs from hierarchical paths
42
+ *
43
+ * REQ-01: JSX → CloudDOM rendering
44
+ * REQ-04: Receives ICloudProvider via dependency injection (not used in build, but available for future extensions)
45
+ */
46
+ export declare class CloudDOMBuilder {
47
+ private cloudProvider;
48
+ /**
49
+ * Optional lifecycle hooks for integration with other components
50
+ * Supports async hooks for validation, telemetry, and provider preparation
51
+ */
52
+ private beforeBuildHook?;
53
+ private afterBuildHook?;
54
+ /**
55
+ * State binding manager for reactive output synchronization
56
+ */
57
+ private stateBindingManager?;
58
+ /**
59
+ * Provider output tracker for instance-output binding
60
+ */
61
+ private providerOutputTracker?;
62
+ /**
63
+ * Track existing nodes to handle re-render scenarios
64
+ * Maps node ID to fiber path for duplicate detection during re-renders
65
+ */
66
+ private existingNodeMap;
67
+ /**
68
+ * Constructor receives ICloudProvider via dependency injection
69
+ *
70
+ * REQ-04: Dependency injection pattern - provider is injected, not inherited
71
+ *
72
+ * @param cloudProvider - Cloud provider implementation (injected)
73
+ */
74
+ constructor(cloudProvider: ICloudProvider);
75
+ /**
76
+ * Set lifecycle hooks for integration with other components
77
+ *
78
+ * Supports async hooks for:
79
+ * - beforeBuild: Validation, pre-processing, telemetry
80
+ * - afterBuild: Provider preparation, post-processing, logging
81
+ *
82
+ * Example:
83
+ * ```typescript
84
+ * builder.setHooks({
85
+ * beforeBuild: async fiber => validator.validate(fiber),
86
+ * afterBuild: async tree => cloudProvider.prepare(tree),
87
+ * });
88
+ * ```
89
+ *
90
+ * @param hooks - Optional lifecycle hooks (sync or async)
91
+ */
92
+ setHooks(hooks: {
93
+ beforeBuild?: (fiber: FiberNode) => void | Promise<void>;
94
+ afterBuild?: (rootNodes: CloudDOMNode[]) => void | Promise<void>;
95
+ }): void;
96
+ /**
97
+ * Set reactive components for output synchronization
98
+ *
99
+ * @param stateBindingManager - State binding manager instance
100
+ * @param providerOutputTracker - Provider output tracker instance
101
+ */
102
+ setReactiveComponents(stateBindingManager: StateBindingManager, providerOutputTracker: ProviderOutputTracker): void;
103
+ /**
104
+ * Build CloudDOM tree from Fiber tree
105
+ *
106
+ * Traverses the Fiber tree and collects nodes that have cloudDOMNode attached
107
+ * (i.e., components that called useInstance). Container components without
108
+ * useInstance are filtered out, but their children are preserved.
109
+ *
110
+ * Supports async lifecycle hooks for validation and provider preparation.
111
+ *
112
+ * REQ-01: Transform Fiber → CloudDOM
113
+ *
114
+ * @param fiber - Root Fiber node
115
+ * @returns Promise resolving to array of CloudDOM nodes (top-level resources)
116
+ */
117
+ build(fiber: FiberNode): Promise<CloudDOMNode[]>;
118
+ /**
119
+ * Build CloudDOM tree with error handling for CLI/CI environments
120
+ *
121
+ * Provides a safer entrypoint that handles errors gracefully without
122
+ * crashing the entire process. Useful for CI/CD pipelines.
123
+ *
124
+ * @param fiber - Root Fiber node
125
+ * @returns Promise resolving to array of CloudDOM nodes, or empty array on error
126
+ */
127
+ buildSafe(fiber: FiberNode): Promise<CloudDOMNode[]>;
128
+ /**
129
+ * Recursively collect CloudDOM nodes from Fiber tree
130
+ *
131
+ * Traverses the Fiber tree depth-first and collects all nodes that have
132
+ * cloudDOMNode or cloudDOMNodes attached (i.e., components that called useInstance).
133
+ *
134
+ * Normalizes paths and IDs during collection for consistency.
135
+ *
136
+ * @param fiber - Current Fiber node
137
+ * @param collected - Array to collect CloudDOM nodes into
138
+ */
139
+ private collectCloudDOMNodes;
140
+ /**
141
+ * Extract state from useState hooks in a Fiber node
142
+ *
143
+ * REQ-02: Extract outputs from useState calls
144
+ * REQ-06: Universal output access
145
+ * REQ-2.1: Store useState values without 'state.' prefix
146
+ *
147
+ * @param fiber - Fiber node to extract state from
148
+ * @returns Object mapping state keys to values (state1, state2, etc.)
149
+ */
150
+ private extractOutputsFromFiber;
151
+ /**
152
+ * Execute post-deployment effects for all Fiber nodes
153
+ * Called after successful deployment to run useEffect callbacks
154
+ *
155
+ * @param fiber - Root Fiber node
156
+ */
157
+ executePostDeploymentEffects(fiber: FiberNode): Promise<void>;
158
+ /**
159
+ * Sync Fiber hook state back to CloudDOM outputs after effects run
160
+ * This ensures useState changes in useEffect are reflected in the CloudDOM
161
+ *
162
+ * @param fiber - Root Fiber node
163
+ * @param cloudDOM - CloudDOM nodes to update
164
+ */
165
+ syncFiberStateToCloudDOM(fiber: FiberNode, cloudDOM: CloudDOMNode[]): void;
166
+ /**
167
+ * Sync a single Fiber node's state to its corresponding CloudDOM node
168
+ */
169
+ private syncFiberNodeToCloudDOM;
170
+ /**
171
+ * Update a CloudDOM node's state with the latest Fiber hook state
172
+ *
173
+ * REQ-1.2, 1.3: Separate useState values from provider outputs
174
+ * State is stored in separate `state` field, not in `outputs`
175
+ */
176
+ private updateCloudDOMNodeOutputs;
177
+ /**
178
+ * Sync state back to the original CloudDOM nodes that components reference
179
+ * This ensures that enhanced node proxies see the updated state
180
+ */
181
+ private syncOutputsToOriginalNodes;
182
+ /**
183
+ * Type guard to validate CloudDOM node structure
184
+ *
185
+ * @param node - Potential CloudDOM node
186
+ * @returns True if node is a valid CloudDOM node
187
+ */
188
+ private isValidCloudNode;
189
+ /**
190
+ * Validate CloudDOM nodes for common issues
191
+ *
192
+ * Checks for:
193
+ * - Duplicate IDs (would cause silent overwrites in hierarchy building)
194
+ * - Invalid paths (empty or non-array)
195
+ * - Circular references in paths
196
+ *
197
+ * Enhanced for re-render scenarios:
198
+ * - Allows re-validation of existing nodes from the same fiber path
199
+ * - Prevents false positives during reactive re-renders
200
+ *
201
+ * @param nodes - CloudDOM nodes to validate
202
+ * @throws Error if duplicate IDs or circular references are found
203
+ */
204
+ private validateCloudDOMNodes;
205
+ /**
206
+ * Create deep defensive copy of CloudDOM nodes to avoid mutation
207
+ *
208
+ * Recursively copies:
209
+ * - Node properties
210
+ * - Props object
211
+ * - Outputs object
212
+ * - Children array (deep copy)
213
+ *
214
+ * This prevents mutations from later phases (e.g., provider injection,
215
+ * dependency graph tagging) from affecting the original nodes.
216
+ *
217
+ * @param nodes - Original CloudDOM nodes
218
+ * @returns Deep copy of nodes
219
+ */
220
+ private createDeepDefensiveCopy;
221
+ /**
222
+ * Build parent-child hierarchy from flat list of CloudDOM nodes
223
+ *
224
+ * Uses the path property to determine parent-child relationships:
225
+ * - A node is a child of another if its path starts with the parent's path
226
+ * - Returns only root nodes (nodes with no parent)
227
+ *
228
+ * Example:
229
+ * - ['registry'] is root
230
+ * - ['registry', 'service'] is child of ['registry']
231
+ * - ['registry', 'service', 'task'] is child of ['registry', 'service']
232
+ *
233
+ * Optimization: Groups nodes by depth for O(n) parent lookup instead of O(n²)
234
+ *
235
+ * @param nodes - Flat array of CloudDOM nodes
236
+ * @returns Array of root CloudDOM nodes with children attached
237
+ */
238
+ private buildHierarchy;
239
+ /**
240
+ * Find the parent node for a given node (optimized version)
241
+ *
242
+ * A node is the parent if:
243
+ * 1. Its path is a prefix of the child's path
244
+ * 2. Its path length is exactly one less than the child's path length (immediate parent)
245
+ *
246
+ * Example:
247
+ * - Child path: ['registry', 'service', 'task']
248
+ * - Parent path: ['registry', 'service'] ✓ (immediate parent)
249
+ * - Not parent: ['registry'] ✗ (grandparent, not immediate)
250
+ *
251
+ * Optimization: Uses nodesByDepth map to only search nodes at parent depth (O(n) instead of O(n²))
252
+ *
253
+ * @param node - Node to find parent for
254
+ * @param nodesByDepth - Map of nodes grouped by path depth
255
+ * @returns Parent node or undefined if no parent
256
+ */
257
+ private findParentOptimized;
258
+ /**
259
+ * Get the cloud provider (for testing/debugging)
260
+ *
261
+ * @returns The injected cloud provider
262
+ */
263
+ getCloudProvider(): ICloudProvider;
264
+ /**
265
+ * Convert CloudDOM tree to flat map for debugging and backend storage
266
+ *
267
+ * Useful for:
268
+ * - Backend state providers that need flat ID → node mapping
269
+ * - Debugging and inspection
270
+ * - Quick lookups by ID
271
+ *
272
+ * Type-safe: Preserves node subtype information for provider-specific extensions
273
+ *
274
+ * @param rootNodes - Root CloudDOM nodes
275
+ * @returns Flat map of ID → CloudDOM node
276
+ */
277
+ toFlatMap<T extends CloudDOMNode = CloudDOMNode>(rootNodes: T[]): Record<string, T>;
278
+ /**
279
+ * Normalize path segments for consistent resource addressing
280
+ *
281
+ * Ensures consistent casing and formatting across environments:
282
+ * - Trims whitespace
283
+ * - Converts to lowercase
284
+ * - Replaces slashes and spaces with hyphens
285
+ *
286
+ * REQ-NF: Future safety for cross-OS consistency
287
+ *
288
+ * @param path - Path segments to normalize
289
+ * @returns Normalized path segments
290
+ */
291
+ private normalizePath;
292
+ /**
293
+ * Format path for human-readable error messages
294
+ *
295
+ * @param node - CloudDOM node
296
+ * @returns Formatted path string (e.g., "registry > service > task")
297
+ */
298
+ private formatPath;
299
+ /**
300
+ * Detect circular references in CloudDOM hierarchy
301
+ *
302
+ * Uses depth-first search to detect cycles in parent-child relationships.
303
+ * This is a graph-level safety check beyond simple path validation.
304
+ *
305
+ * @param nodes - Root CloudDOM nodes
306
+ * @throws Error if circular hierarchy is detected
307
+ */
308
+ private detectCircularRefs;
309
+ /**
310
+ * Build efficient node map for CloudDOM comparison
311
+ * Creates a flat map of node ID to node for fast lookup during comparison
312
+ * Handles nested node structures properly
313
+ *
314
+ * REQ-1.4, 9.1: Efficient map building for CloudDOM comparison
315
+ *
316
+ * @param nodes - CloudDOM nodes to map
317
+ * @returns Map of node ID to CloudDOM node
318
+ */
319
+ private buildNodeMap;
320
+ /**
321
+ * Detect output changes after deployment by comparing previous and current CloudDOM
322
+ * This is called after deployment to identify which provider outputs have changed
323
+ *
324
+ * Enhanced to:
325
+ * - Compare previous and current CloudDOM states properly
326
+ * - Identify specific output keys that changed
327
+ * - Track affected fibers for each change
328
+ *
329
+ * REQ-1.4, 1.5, 9.1, 9.2, 9.3: Enhanced output change detection
330
+ *
331
+ * @param previous - Previous CloudDOM state
332
+ * @param current - Current CloudDOM state after deployment
333
+ * @returns Array of output changes detected
334
+ */
335
+ detectOutputChanges(previous: CloudDOMNode[], current: CloudDOMNode[]): OutputChange[];
336
+ /**
337
+ * Synchronize provider outputs to bound state and trigger re-renders
338
+ * This is the main method called after deployment to update reactive state
339
+ *
340
+ * @param fiber - Root fiber node
341
+ * @param cloudDOM - Current CloudDOM after deployment
342
+ * @param previousCloudDOM - Previous CloudDOM state (optional)
343
+ * @returns Promise resolving to affected fibers that need re-rendering
344
+ */
345
+ syncOutputsAndReRender(fiber: FiberNode, cloudDOM: CloudDOMNode[], previousCloudDOM?: CloudDOMNode[]): Promise<FiberNode[]>;
346
+ /**
347
+ * Sync CloudDOM outputs to the original nodes that components reference
348
+ * This is critical for reactivity to work - components need to see updated outputs
349
+ */
350
+ private syncCloudDOMOutputsToOriginalNodes;
351
+ /**
352
+ * Recursively sync outputs to original nodes in the fiber tree
353
+ */
354
+ private syncOutputsToOriginalNodesRecursive;
355
+ /**
356
+ * Update context provider values when outputs change
357
+ * This enables context reactivity by finding components that create context values from outputs
358
+ *
359
+ * Strategy:
360
+ * 1. Find all fibers that have both cloudDOMNodes (use outputs) AND render a Context.Provider child
361
+ * 2. These are the components that create context values from outputs
362
+ * 3. Mark them for re-render so they re-evaluate their context values
363
+ *
364
+ * @param fiber - Root fiber to search
365
+ * @returns Array of fibers that need re-rendering (components creating context values from outputs)
366
+ */
367
+ private updateContextProviderValues;
368
+ /**
369
+ * Recursively find components that create context values from outputs
370
+ * These are components that:
371
+ * 1. Have cloudDOMNodes (use useInstance - depend on outputs)
372
+ * 2. Have children that are Context.Provider components
373
+ */
374
+ private findContextValueCreators;
375
+ /**
376
+ * Apply output changes to bound state using StateBindingManager
377
+ * This updates useState values that are bound to provider outputs
378
+ *
379
+ * Enhanced to:
380
+ * - Apply detected changes to bound state via StateBindingManager
381
+ * - Handle binding updates without creating loops
382
+ * - Return affected fibers for re-rendering
383
+ *
384
+ * REQ-9.4, 9.5: Apply output changes to state and return affected fibers
385
+ *
386
+ * @param changes - Array of output changes to apply
387
+ * @returns Array of fibers affected by the changes
388
+ */
389
+ applyOutputChangesToState(changes: OutputChange[]): FiberNode[];
390
+ /**
391
+ * Execute reactive effects for fibers affected by output changes
392
+ * This triggers useEffect callbacks that depend on changed provider outputs
393
+ *
394
+ * @param affectedFibers - Fibers that were affected by output changes
395
+ * @param changes - Output changes that occurred
396
+ */
397
+ private executeReactiveEffects;
398
+ /**
399
+ * Integrate with post-deployment effects to trigger output synchronization
400
+ * This method should be called after deployment completes
401
+ *
402
+ * Phase ordering (REQ-1.1, 1.2, 1.5):
403
+ * 1. Sync outputs to original nodes BEFORE executing effects
404
+ * 2. Execute effects (they can now see updated outputs)
405
+ * 3. Sync outputs and trigger re-renders for reactive changes
406
+ * 4. Sync state changes back to CloudDOM
407
+ *
408
+ * @param fiber - Root fiber node
409
+ * @param cloudDOM - Current CloudDOM after deployment
410
+ * @param previousCloudDOM - Previous CloudDOM state (optional)
411
+ * @returns Promise resolving to affected fibers that need re-rendering
412
+ */
413
+ integrateWithPostDeploymentEffects(fiber: FiberNode, cloudDOM: CloudDOMNode[], previousCloudDOM?: CloudDOMNode[]): Promise<FiberNode[]>;
414
+ /**
415
+ * Clear the existing node map (for testing or fresh builds)
416
+ * This allows starting with a clean slate for node validation
417
+ */
418
+ clearExistingNodes(): void;
419
+ /**
420
+ * Get the existing node map (for debugging/inspection)
421
+ * Returns a copy to prevent external mutation
422
+ */
423
+ getExistingNodes(): Map<string, string>;
424
+ /**
425
+ * Create a JSON replacer function that handles Symbols safely
426
+ * Converts Symbols to their string representation for debugging
427
+ */
428
+ private createSymbolReplacer;
429
+ }