@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.
- package/LICENSE +212 -0
- package/README.md +379 -0
- package/dist/cli/commands/BuildCommand.d.ts +40 -0
- package/dist/cli/commands/BuildCommand.js +151 -0
- package/dist/cli/commands/DeployCommand.d.ts +38 -0
- package/dist/cli/commands/DeployCommand.js +194 -0
- package/dist/cli/commands/DevCommand.d.ts +52 -0
- package/dist/cli/commands/DevCommand.js +385 -0
- package/dist/cli/commands/PlanCommand.d.ts +39 -0
- package/dist/cli/commands/PlanCommand.js +164 -0
- package/dist/cli/commands/index.d.ts +36 -0
- package/dist/cli/commands/index.js +43 -0
- package/dist/cli/core/ArgumentParser.d.ts +46 -0
- package/dist/cli/core/ArgumentParser.js +127 -0
- package/dist/cli/core/BaseCommand.d.ts +75 -0
- package/dist/cli/core/BaseCommand.js +95 -0
- package/dist/cli/core/CLIContext.d.ts +68 -0
- package/dist/cli/core/CLIContext.js +183 -0
- package/dist/cli/core/CommandRegistry.d.ts +64 -0
- package/dist/cli/core/CommandRegistry.js +89 -0
- package/dist/cli/core/index.d.ts +36 -0
- package/dist/cli/core/index.js +43 -0
- package/dist/cli/index.d.ts +35 -0
- package/dist/cli/index.js +100 -0
- package/dist/cli/output.d.ts +204 -0
- package/dist/cli/output.js +437 -0
- package/dist/cli/utils.d.ts +59 -0
- package/dist/cli/utils.js +76 -0
- package/dist/context/createContext.d.ts +90 -0
- package/dist/context/createContext.js +113 -0
- package/dist/context/index.d.ts +30 -0
- package/dist/context/index.js +35 -0
- package/dist/core/CReact.d.ts +409 -0
- package/dist/core/CReact.js +1127 -0
- package/dist/core/CloudDOMBuilder.d.ts +429 -0
- package/dist/core/CloudDOMBuilder.js +1198 -0
- package/dist/core/ContextDependencyTracker.d.ts +165 -0
- package/dist/core/ContextDependencyTracker.js +448 -0
- package/dist/core/ErrorRecoveryManager.d.ts +145 -0
- package/dist/core/ErrorRecoveryManager.js +443 -0
- package/dist/core/EventBus.d.ts +91 -0
- package/dist/core/EventBus.js +185 -0
- package/dist/core/ProviderOutputTracker.d.ts +211 -0
- package/dist/core/ProviderOutputTracker.js +476 -0
- package/dist/core/ReactiveUpdateQueue.d.ts +76 -0
- package/dist/core/ReactiveUpdateQueue.js +121 -0
- package/dist/core/Reconciler.d.ts +415 -0
- package/dist/core/Reconciler.js +1037 -0
- package/dist/core/RenderScheduler.d.ts +153 -0
- package/dist/core/RenderScheduler.js +519 -0
- package/dist/core/Renderer.d.ts +276 -0
- package/dist/core/Renderer.js +791 -0
- package/dist/core/Runtime.d.ts +246 -0
- package/dist/core/Runtime.js +640 -0
- package/dist/core/StateBindingManager.d.ts +121 -0
- package/dist/core/StateBindingManager.js +309 -0
- package/dist/core/StateMachine.d.ts +424 -0
- package/dist/core/StateMachine.js +787 -0
- package/dist/core/StructuralChangeDetector.d.ts +140 -0
- package/dist/core/StructuralChangeDetector.js +363 -0
- package/dist/core/Validator.d.ts +127 -0
- package/dist/core/Validator.js +279 -0
- package/dist/core/errors.d.ts +153 -0
- package/dist/core/errors.js +202 -0
- package/dist/core/index.d.ts +38 -0
- package/dist/core/index.js +64 -0
- package/dist/core/types.d.ts +263 -0
- package/dist/core/types.js +48 -0
- package/dist/hooks/context.d.ts +147 -0
- package/dist/hooks/context.js +334 -0
- package/dist/hooks/useContext.d.ts +113 -0
- package/dist/hooks/useContext.js +169 -0
- package/dist/hooks/useEffect.d.ts +105 -0
- package/dist/hooks/useEffect.js +540 -0
- package/dist/hooks/useInstance.d.ts +139 -0
- package/dist/hooks/useInstance.js +441 -0
- package/dist/hooks/useState.d.ts +120 -0
- package/dist/hooks/useState.js +298 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +70 -0
- package/dist/jsx.d.ts +64 -0
- package/dist/jsx.js +76 -0
- package/dist/providers/DummyBackendProvider.d.ts +193 -0
- package/dist/providers/DummyBackendProvider.js +189 -0
- package/dist/providers/DummyCloudProvider.d.ts +128 -0
- package/dist/providers/DummyCloudProvider.js +157 -0
- package/dist/providers/IBackendProvider.d.ts +177 -0
- package/dist/providers/IBackendProvider.js +31 -0
- package/dist/providers/ICloudProvider.d.ts +146 -0
- package/dist/providers/ICloudProvider.js +31 -0
- package/dist/providers/index.d.ts +31 -0
- package/dist/providers/index.js +31 -0
- package/dist/test-event-callbacks.d.ts +0 -0
- package/dist/test-event-callbacks.js +1 -0
- package/dist/utils/Logger.d.ts +144 -0
- package/dist/utils/Logger.js +220 -0
- package/dist/utils/Output.d.ts +161 -0
- package/dist/utils/Output.js +401 -0
- package/dist/utils/deepEqual.d.ts +71 -0
- package/dist/utils/deepEqual.js +276 -0
- package/dist/utils/naming.d.ts +241 -0
- package/dist/utils/naming.js +376 -0
- package/package.json +87 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
|
|
10
|
+
*
|
|
11
|
+
|
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
|
|
14
|
+
*
|
|
15
|
+
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
|
|
18
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
+
|
|
20
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
|
|
22
|
+
* See the License for the specific language governing permissions and
|
|
23
|
+
|
|
24
|
+
* limitations under the License.
|
|
25
|
+
|
|
26
|
+
*
|
|
27
|
+
|
|
28
|
+
* Copyright 2025 Daniel Coutinho Ribeiro
|
|
29
|
+
|
|
30
|
+
*/
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.setStateBindingManager = setStateBindingManager;
|
|
33
|
+
exports.getStateBindingManagerInstance = getStateBindingManagerInstance;
|
|
34
|
+
exports.setStateRenderContext = setStateRenderContext;
|
|
35
|
+
exports.clearStateRenderContext = clearStateRenderContext;
|
|
36
|
+
exports.useState = useState;
|
|
37
|
+
exports.hasStateContext = hasStateContext;
|
|
38
|
+
exports.getCurrentState = getCurrentState;
|
|
39
|
+
// REQ-02: useState hook for declarative output binding
|
|
40
|
+
// This hook declares component outputs that persist across build/deploy cycles
|
|
41
|
+
const context_1 = require("./context");
|
|
42
|
+
const StateBindingManager_1 = require("../core/StateBindingManager");
|
|
43
|
+
const naming_1 = require("../utils/naming");
|
|
44
|
+
const ReactiveUpdateQueue_1 = require("../core/ReactiveUpdateQueue");
|
|
45
|
+
const Logger_1 = require("../utils/Logger");
|
|
46
|
+
const logger = Logger_1.LoggerFactory.getLogger('hooks');
|
|
47
|
+
const CReact_1 = require("../core/CReact");
|
|
48
|
+
// Global StateBindingManager instance
|
|
49
|
+
let stateBindingManager = null;
|
|
50
|
+
/**
|
|
51
|
+
* Get or create the global StateBindingManager instance
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
function getStateBindingManager() {
|
|
55
|
+
if (!stateBindingManager) {
|
|
56
|
+
stateBindingManager = new StateBindingManager_1.StateBindingManager();
|
|
57
|
+
}
|
|
58
|
+
return stateBindingManager;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Set the StateBindingManager instance (for testing/injection)
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
function setStateBindingManager(manager) {
|
|
65
|
+
stateBindingManager = manager;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get the StateBindingManager instance (for external access)
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
function getStateBindingManagerInstance() {
|
|
72
|
+
return getStateBindingManager();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Set the current rendering context for useState
|
|
76
|
+
* Called by Renderer before executing a component
|
|
77
|
+
*
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
function setStateRenderContext(fiber, path) {
|
|
81
|
+
(0, context_1.setRenderContext)(fiber, path);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Clear the current rendering context for useState
|
|
85
|
+
* Called by Renderer after component execution
|
|
86
|
+
*
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
function clearStateRenderContext() {
|
|
90
|
+
(0, context_1.clearRenderContext)();
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* useState hook - Declare component outputs (NOT reactive state)
|
|
94
|
+
*
|
|
95
|
+
* This hook declares outputs that will be persisted across build/deploy cycles.
|
|
96
|
+
* Unlike React's useState, this does NOT trigger re-renders.
|
|
97
|
+
*
|
|
98
|
+
* Mimics React's useState API with hooks array pattern for multiple calls.
|
|
99
|
+
*
|
|
100
|
+
* REQ-02: Stack Context (declarative outputs)
|
|
101
|
+
*
|
|
102
|
+
* Semantics:
|
|
103
|
+
* - `useState(initialValue)` - Declares a single output value
|
|
104
|
+
* - `setState(value)` during build - Updates the output value for build-time enrichment
|
|
105
|
+
* - `setState(value)` during deploy - Updates persisted output after provider materialization
|
|
106
|
+
* - NOT a render trigger - it's a persistent output update mechanism
|
|
107
|
+
* - Supports multiple useState calls per component (like React)
|
|
108
|
+
*
|
|
109
|
+
* Key difference from React:
|
|
110
|
+
* - React: `setState()` causes re-render in memory
|
|
111
|
+
* - CReact: `setState()` updates persisted outputs for next cycle
|
|
112
|
+
*
|
|
113
|
+
* @param initialValue - Initial output value to declare
|
|
114
|
+
* @returns Tuple of [state, setState] where setState updates the output value
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```tsx
|
|
118
|
+
* function CDNStack({ children }) {
|
|
119
|
+
* const distribution = useInstance('cdn', CloudFrontDistribution, { ... });
|
|
120
|
+
*
|
|
121
|
+
* // Multiple useState calls (like React)
|
|
122
|
+
* const [distributionId, setDistributionId] = useState<string>();
|
|
123
|
+
* const [distributionDomain, setDistributionDomain] = useState<string>();
|
|
124
|
+
* const [distributionArn, setDistributionArn] = useState<string>();
|
|
125
|
+
*
|
|
126
|
+
* // Optional: Enrich outputs after async materialization
|
|
127
|
+
* useEffect(async () => {
|
|
128
|
+
* const actualDomain = await distribution.getDomain();
|
|
129
|
+
* setDistributionDomain(actualDomain);
|
|
130
|
+
* }, [distribution]);
|
|
131
|
+
*
|
|
132
|
+
* // Aggregate outputs for StackContext
|
|
133
|
+
* const outputs = {
|
|
134
|
+
* distributionId,
|
|
135
|
+
* distributionDomain,
|
|
136
|
+
* distributionArn,
|
|
137
|
+
* };
|
|
138
|
+
*
|
|
139
|
+
* return <StackContext.Provider value={outputs}>{children}</StackContext.Provider>;
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
function useState(initialValue) {
|
|
144
|
+
// Use consolidated hook context
|
|
145
|
+
const context = (0, context_1.requireHookContext)();
|
|
146
|
+
const currentFiber = context.currentFiber; // Non-null assertion safe due to requireHookContext validation
|
|
147
|
+
// Initialize hooks array in Fiber node if not already present
|
|
148
|
+
if (!currentFiber.hooks) {
|
|
149
|
+
currentFiber.hooks = [];
|
|
150
|
+
}
|
|
151
|
+
// Get current hook index and increment for next call (state-specific)
|
|
152
|
+
const currentHookIndex = (0, context_1.incrementHookIndex)('state');
|
|
153
|
+
// Initialize this hook's state if first render
|
|
154
|
+
if (currentFiber.hooks[currentHookIndex] === undefined) {
|
|
155
|
+
// CRITICAL: Check for hydrated value first (hot reload state restoration)
|
|
156
|
+
// This allows useState to restore persisted state instead of using initial value
|
|
157
|
+
let hydratedValue = undefined;
|
|
158
|
+
// Try to get CReact instance to check for hydration data
|
|
159
|
+
try {
|
|
160
|
+
const creactInstance = (0, CReact_1.getCReactInstance)?.();
|
|
161
|
+
if (creactInstance && creactInstance.hasHydrationData()) {
|
|
162
|
+
// CRITICAL: The fiber path is the component path (e.g., 'web-app-stack')
|
|
163
|
+
const fiberPath = currentFiber.path?.join('.') || '';
|
|
164
|
+
logger.debug(`🔍 Looking for hydration: component="${fiberPath}", hookIndex=${currentHookIndex}`);
|
|
165
|
+
// Try to get hydration from component path
|
|
166
|
+
hydratedValue = creactInstance.getHydratedValueForComponent(fiberPath, currentHookIndex);
|
|
167
|
+
if (hydratedValue !== undefined) {
|
|
168
|
+
logger.debug(`✅ HYDRATION SUCCESS for ${fiberPath}[${currentHookIndex}]:`, hydratedValue);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
logger.debug(`❌ HYDRATION FAILED for ${fiberPath}[${currentHookIndex}]`);
|
|
172
|
+
logger.debug(` Available hydration keys:`, creactInstance.getHydrationMapKeys?.() || 'N/A');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
logger.debug(`⚠️ No hydration data available (instance=${!!creactInstance}, hasData=${creactInstance?.hasHydrationData()})`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
// Hydration is optional, continue with initial value if it fails
|
|
181
|
+
logger.warn('⚠️ Hydration check failed:', error);
|
|
182
|
+
logger.debug('Stack:', error.stack);
|
|
183
|
+
}
|
|
184
|
+
// Use hydrated value if available, otherwise use initial value
|
|
185
|
+
const finalValue = hydratedValue !== undefined ? hydratedValue : initialValue;
|
|
186
|
+
currentFiber.hooks[currentHookIndex] = finalValue;
|
|
187
|
+
logger.debug(`📝 Initialized hook[${currentHookIndex}] = ${JSON.stringify(finalValue)} (hydrated=${hydratedValue !== undefined})`);
|
|
188
|
+
}
|
|
189
|
+
// Store the fiber and hook index for later access
|
|
190
|
+
const fiber = currentFiber;
|
|
191
|
+
const hookIdx = currentHookIndex;
|
|
192
|
+
/**
|
|
193
|
+
* setState function - Updates the output value with reactive capabilities
|
|
194
|
+
*
|
|
195
|
+
* This function updates the persisted output in the Fiber node's hooks array.
|
|
196
|
+
* It now includes:
|
|
197
|
+
* - Change detection to avoid unnecessary updates
|
|
198
|
+
* - Automatic binding detection for provider outputs
|
|
199
|
+
* - Integration with StateBindingManager for reactive updates
|
|
200
|
+
* - REQ-4.1, 4.2, 4.3: Internal update mechanism to prevent circular dependencies
|
|
201
|
+
*
|
|
202
|
+
* During build: Collects values known at build-time
|
|
203
|
+
* During deploy: Patches in async resources (queue URLs, ARNs)
|
|
204
|
+
*
|
|
205
|
+
* @param value - New value or updater function
|
|
206
|
+
* @param isInternalUpdate - If true, skip binding creation (prevents loops)
|
|
207
|
+
*/
|
|
208
|
+
const setState = (value, isInternalUpdate = false) => {
|
|
209
|
+
// Resolve value (handle both direct value and function forms)
|
|
210
|
+
const newValue = typeof value === 'function' ? value(fiber.hooks?.[hookIdx]) : value;
|
|
211
|
+
const oldValue = fiber.hooks?.[hookIdx];
|
|
212
|
+
// Debug logging (before change check for better visibility)
|
|
213
|
+
if (process.env.CREACT_DEBUG === 'true') {
|
|
214
|
+
const safeStringify = (value) => {
|
|
215
|
+
try {
|
|
216
|
+
return JSON.stringify(value);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return String(value);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
logger.debug(`setState called: hookIdx=${hookIdx}, oldValue=${safeStringify(oldValue)}, newValue=${safeStringify(newValue)}, isInternal=${isInternalUpdate}, fiber.id=${fiber.path?.join('.')}`);
|
|
223
|
+
}
|
|
224
|
+
// Only proceed if value actually changed
|
|
225
|
+
if (oldValue === newValue) {
|
|
226
|
+
logger.debug(`No change detected, skipping update`);
|
|
227
|
+
return; // No change, skip update
|
|
228
|
+
}
|
|
229
|
+
// Update this hook's state
|
|
230
|
+
if (fiber.hooks) {
|
|
231
|
+
fiber.hooks[hookIdx] = newValue;
|
|
232
|
+
}
|
|
233
|
+
// REQ-4.2: Only create bindings for user updates, not internal ones
|
|
234
|
+
// This prevents infinite binding loops when StateBindingManager updates state
|
|
235
|
+
if (!isInternalUpdate) {
|
|
236
|
+
// Check if the new value is a provider output and create automatic binding
|
|
237
|
+
const bindingManager = getStateBindingManager();
|
|
238
|
+
const outputInfo = bindingManager.isProviderOutput(newValue);
|
|
239
|
+
if (outputInfo) {
|
|
240
|
+
// REQ-4.1, 4.3: Prevent infinite binding loops during reactivity
|
|
241
|
+
// Only bind if this state is not already bound to this output
|
|
242
|
+
if (!bindingManager.isStateBoundToOutput(fiber, hookIdx)) {
|
|
243
|
+
// Automatically bind this state to the provider output
|
|
244
|
+
bindingManager.bindStateToOutput(fiber, hookIdx, outputInfo.nodeId, outputInfo.outputKey, newValue);
|
|
245
|
+
const bindingKey = (0, naming_1.generateBindingKey)(outputInfo.nodeId, outputInfo.outputKey);
|
|
246
|
+
logger.debug(`Auto-bound state to output: ${bindingKey}`);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
const bindingKey = (0, naming_1.generateBindingKey)(outputInfo.nodeId, outputInfo.outputKey);
|
|
250
|
+
logger.debug(`Skipped re-binding already bound state: ${bindingKey}`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
logger.debug(`Skipped binding check for internal update`);
|
|
256
|
+
}
|
|
257
|
+
// REQ-4.4: Mark fiber as dirty and enqueue for re-render
|
|
258
|
+
// This is critical for initial deployment where outputs go from undefined → value
|
|
259
|
+
// The fiber will be collected by the reactivity phase and re-rendered
|
|
260
|
+
if (!isInternalUpdate && oldValue !== newValue) {
|
|
261
|
+
// Mark this fiber as having state changes
|
|
262
|
+
if (!fiber.__stateChanged) {
|
|
263
|
+
fiber.__stateChanged = true;
|
|
264
|
+
}
|
|
265
|
+
// Enqueue fiber for re-rendering in reactivity phase
|
|
266
|
+
const queue = (0, ReactiveUpdateQueue_1.getReactiveUpdateQueue)();
|
|
267
|
+
queue.enqueue(fiber);
|
|
268
|
+
logger.debug(`Enqueued fiber ${fiber.path?.join('.')} for re-render (queue size: ${queue.size()})`);
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
// REQ-4.1, 4.2: Store setState callback in fiber for internal updates
|
|
272
|
+
// This allows StateBindingManager to update state without creating new bindings
|
|
273
|
+
if (!fiber.setStateCallbacks) {
|
|
274
|
+
fiber.setStateCallbacks = [];
|
|
275
|
+
}
|
|
276
|
+
fiber.setStateCallbacks[hookIdx] = setState;
|
|
277
|
+
// Get current state for this hook - read it fresh each time
|
|
278
|
+
// This ensures synchronous setState calls during render are reflected
|
|
279
|
+
const state = (fiber.hooks && fiber.hooks[hookIdx]);
|
|
280
|
+
return [state, setState];
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Check if useState context is available
|
|
284
|
+
* Useful for validation and testing
|
|
285
|
+
*
|
|
286
|
+
* @internal
|
|
287
|
+
*/
|
|
288
|
+
function hasStateContext() {
|
|
289
|
+
return (0, context_1.hasRenderContext)();
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Get the current state from Fiber (for testing)
|
|
293
|
+
*
|
|
294
|
+
* @internal
|
|
295
|
+
*/
|
|
296
|
+
function getCurrentState() {
|
|
297
|
+
return (0, context_1.getCurrentState)();
|
|
298
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
export { CReact, JSXElement } from './jsx';
|
|
31
|
+
export type { FC, PropsWithChildren } from './jsx.d';
|
|
32
|
+
import { CReact as CReactClass } from './core/CReact';
|
|
33
|
+
export { CReact as CReactCore, CReactConfig } from './core/CReact';
|
|
34
|
+
export declare const renderCloudDOM: typeof CReactClass.renderCloudDOM;
|
|
35
|
+
export { Renderer } from './core/Renderer';
|
|
36
|
+
export { Validator } from './core/Validator';
|
|
37
|
+
export { CloudDOMBuilder } from './core/CloudDOMBuilder';
|
|
38
|
+
export { FiberNode, CloudDOMNode } from './core/types';
|
|
39
|
+
export { ICloudProvider } from './providers/ICloudProvider';
|
|
40
|
+
export { IBackendProvider } from './providers/IBackendProvider';
|
|
41
|
+
export { useInstance } from './hooks/useInstance';
|
|
42
|
+
export { useState } from './hooks/useState';
|
|
43
|
+
export { useContext } from './hooks/useContext';
|
|
44
|
+
export { useEffect } from './hooks/useEffect';
|
|
45
|
+
export { createContext, Context } from './context';
|
|
46
|
+
export { generateResourceId, toKebabCase, getNodeName, validateIdUniqueness, normalizePathSegment, normalizePath, formatPath, parseResourceId, } from './utils/naming';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
|
|
10
|
+
*
|
|
11
|
+
|
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
|
|
14
|
+
*
|
|
15
|
+
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
|
|
18
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
+
|
|
20
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
|
|
22
|
+
* See the License for the specific language governing permissions and
|
|
23
|
+
|
|
24
|
+
* limitations under the License.
|
|
25
|
+
|
|
26
|
+
*
|
|
27
|
+
|
|
28
|
+
* Copyright 2025 Daniel Coutinho Ribeiro
|
|
29
|
+
|
|
30
|
+
*/
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.parseResourceId = exports.formatPath = exports.normalizePath = exports.normalizePathSegment = exports.validateIdUniqueness = exports.getNodeName = exports.toKebabCase = exports.generateResourceId = exports.createContext = exports.useEffect = exports.useContext = exports.useState = exports.useInstance = exports.CloudDOMBuilder = exports.Validator = exports.Renderer = exports.renderCloudDOM = exports.CReactCore = exports.CReact = void 0;
|
|
33
|
+
// CReact - Infrastructure as Code with JSX
|
|
34
|
+
// Main entry point for the library
|
|
35
|
+
// JSX support
|
|
36
|
+
var jsx_1 = require("./jsx");
|
|
37
|
+
Object.defineProperty(exports, "CReact", { enumerable: true, get: function () { return jsx_1.CReact; } });
|
|
38
|
+
// Core classes
|
|
39
|
+
const CReact_1 = require("./core/CReact");
|
|
40
|
+
var CReact_2 = require("./core/CReact");
|
|
41
|
+
Object.defineProperty(exports, "CReactCore", { enumerable: true, get: function () { return CReact_2.CReact; } });
|
|
42
|
+
exports.renderCloudDOM = CReact_1.CReact.renderCloudDOM;
|
|
43
|
+
var Renderer_1 = require("./core/Renderer");
|
|
44
|
+
Object.defineProperty(exports, "Renderer", { enumerable: true, get: function () { return Renderer_1.Renderer; } });
|
|
45
|
+
var Validator_1 = require("./core/Validator");
|
|
46
|
+
Object.defineProperty(exports, "Validator", { enumerable: true, get: function () { return Validator_1.Validator; } });
|
|
47
|
+
var CloudDOMBuilder_1 = require("./core/CloudDOMBuilder");
|
|
48
|
+
Object.defineProperty(exports, "CloudDOMBuilder", { enumerable: true, get: function () { return CloudDOMBuilder_1.CloudDOMBuilder; } });
|
|
49
|
+
// Hooks
|
|
50
|
+
var useInstance_1 = require("./hooks/useInstance");
|
|
51
|
+
Object.defineProperty(exports, "useInstance", { enumerable: true, get: function () { return useInstance_1.useInstance; } });
|
|
52
|
+
var useState_1 = require("./hooks/useState");
|
|
53
|
+
Object.defineProperty(exports, "useState", { enumerable: true, get: function () { return useState_1.useState; } });
|
|
54
|
+
var useContext_1 = require("./hooks/useContext");
|
|
55
|
+
Object.defineProperty(exports, "useContext", { enumerable: true, get: function () { return useContext_1.useContext; } });
|
|
56
|
+
var useEffect_1 = require("./hooks/useEffect");
|
|
57
|
+
Object.defineProperty(exports, "useEffect", { enumerable: true, get: function () { return useEffect_1.useEffect; } });
|
|
58
|
+
// Context API
|
|
59
|
+
var context_1 = require("./context");
|
|
60
|
+
Object.defineProperty(exports, "createContext", { enumerable: true, get: function () { return context_1.createContext; } });
|
|
61
|
+
// Utilities
|
|
62
|
+
var naming_1 = require("./utils/naming");
|
|
63
|
+
Object.defineProperty(exports, "generateResourceId", { enumerable: true, get: function () { return naming_1.generateResourceId; } });
|
|
64
|
+
Object.defineProperty(exports, "toKebabCase", { enumerable: true, get: function () { return naming_1.toKebabCase; } });
|
|
65
|
+
Object.defineProperty(exports, "getNodeName", { enumerable: true, get: function () { return naming_1.getNodeName; } });
|
|
66
|
+
Object.defineProperty(exports, "validateIdUniqueness", { enumerable: true, get: function () { return naming_1.validateIdUniqueness; } });
|
|
67
|
+
Object.defineProperty(exports, "normalizePathSegment", { enumerable: true, get: function () { return naming_1.normalizePathSegment; } });
|
|
68
|
+
Object.defineProperty(exports, "normalizePath", { enumerable: true, get: function () { return naming_1.normalizePath; } });
|
|
69
|
+
Object.defineProperty(exports, "formatPath", { enumerable: true, get: function () { return naming_1.formatPath; } });
|
|
70
|
+
Object.defineProperty(exports, "parseResourceId", { enumerable: true, get: function () { return naming_1.parseResourceId; } });
|
package/dist/jsx.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
/**
|
|
31
|
+
* JSX factory for CReact
|
|
32
|
+
*
|
|
33
|
+
* This module provides the createElement factory function that TypeScript
|
|
34
|
+
* uses to transform JSX syntax into function calls.
|
|
35
|
+
*
|
|
36
|
+
* Example transformation:
|
|
37
|
+
* <Component prop="value" />
|
|
38
|
+
* → CReact.createElement(Component, { prop: "value" })
|
|
39
|
+
*/
|
|
40
|
+
export interface JSXElement {
|
|
41
|
+
type: any;
|
|
42
|
+
props: Record<string, any>;
|
|
43
|
+
key?: string | number;
|
|
44
|
+
}
|
|
45
|
+
export declare namespace CReact {
|
|
46
|
+
/**
|
|
47
|
+
* JSX factory function called by TypeScript when transforming JSX
|
|
48
|
+
*
|
|
49
|
+
* @param type - Component function or string (for intrinsic elements)
|
|
50
|
+
* @param props - Props object (may include key and children)
|
|
51
|
+
* @param children - Child elements (variadic)
|
|
52
|
+
* @returns JSXElement object with normalized props
|
|
53
|
+
*/
|
|
54
|
+
function createElement(type: any, props: Record<string, any> | null, ...children: any[]): JSXElement;
|
|
55
|
+
/**
|
|
56
|
+
* Fragment symbol for <>...</> syntax
|
|
57
|
+
* Fragments allow grouping multiple children without adding extra nodes
|
|
58
|
+
*
|
|
59
|
+
* Note: Fragment is a Symbol at runtime, but typed as a function for JSX compatibility
|
|
60
|
+
*/
|
|
61
|
+
const Fragment: (props: {
|
|
62
|
+
children?: any;
|
|
63
|
+
}) => JSXElement;
|
|
64
|
+
}
|
package/dist/jsx.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
|
|
10
|
+
*
|
|
11
|
+
|
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
|
|
14
|
+
*
|
|
15
|
+
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
|
|
18
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
+
|
|
20
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
|
|
22
|
+
* See the License for the specific language governing permissions and
|
|
23
|
+
|
|
24
|
+
* limitations under the License.
|
|
25
|
+
|
|
26
|
+
*
|
|
27
|
+
|
|
28
|
+
* Copyright 2025 Daniel Coutinho Ribeiro
|
|
29
|
+
|
|
30
|
+
*/
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.CReact = void 0;
|
|
33
|
+
var CReact;
|
|
34
|
+
(function (CReact) {
|
|
35
|
+
/**
|
|
36
|
+
* JSX factory function called by TypeScript when transforming JSX
|
|
37
|
+
*
|
|
38
|
+
* @param type - Component function or string (for intrinsic elements)
|
|
39
|
+
* @param props - Props object (may include key and children)
|
|
40
|
+
* @param children - Child elements (variadic)
|
|
41
|
+
* @returns JSXElement object with normalized props
|
|
42
|
+
*/
|
|
43
|
+
function createElement(type, props, ...children) {
|
|
44
|
+
// Normalize props (handle null case)
|
|
45
|
+
const normalizedProps = props ? { ...props } : {};
|
|
46
|
+
// Extract key from props if present
|
|
47
|
+
const key = normalizedProps.key;
|
|
48
|
+
delete normalizedProps.key;
|
|
49
|
+
// Handle children normalization
|
|
50
|
+
if (children.length > 0) {
|
|
51
|
+
// Flatten children array and filter out null/undefined
|
|
52
|
+
const flattenedChildren = children.flat().filter((child) => child != null);
|
|
53
|
+
// Single child: store as-is
|
|
54
|
+
// Multiple children: store as array
|
|
55
|
+
if (flattenedChildren.length === 1) {
|
|
56
|
+
normalizedProps.children = flattenedChildren[0];
|
|
57
|
+
}
|
|
58
|
+
else if (flattenedChildren.length > 1) {
|
|
59
|
+
normalizedProps.children = flattenedChildren;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
type,
|
|
64
|
+
props: normalizedProps,
|
|
65
|
+
key,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
CReact.createElement = createElement;
|
|
69
|
+
/**
|
|
70
|
+
* Fragment symbol for <>...</> syntax
|
|
71
|
+
* Fragments allow grouping multiple children without adding extra nodes
|
|
72
|
+
*
|
|
73
|
+
* Note: Fragment is a Symbol at runtime, but typed as a function for JSX compatibility
|
|
74
|
+
*/
|
|
75
|
+
CReact.Fragment = Symbol.for('CReact.Fragment');
|
|
76
|
+
})(CReact || (exports.CReact = CReact = {}));
|