@creact-labs/creact 0.1.7 → 0.2.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 (146) hide show
  1. package/README.md +72 -21
  2. package/dist/cli.d.ts +11 -0
  3. package/dist/cli.js +88 -0
  4. package/dist/index.d.ts +19 -44
  5. package/dist/index.js +20 -68
  6. package/dist/jsx/index.d.ts +2 -0
  7. package/dist/jsx/index.js +1 -0
  8. package/dist/jsx/jsx-dev-runtime.d.ts +4 -0
  9. package/dist/jsx/jsx-dev-runtime.js +4 -0
  10. package/dist/jsx/jsx-runtime.d.ts +38 -0
  11. package/dist/jsx/jsx-runtime.js +38 -0
  12. package/dist/jsx/types.d.ts +12 -0
  13. package/dist/jsx/types.js +4 -0
  14. package/dist/primitives/context.d.ts +34 -0
  15. package/dist/primitives/context.js +63 -0
  16. package/dist/primitives/index.d.ts +3 -0
  17. package/dist/primitives/index.js +3 -0
  18. package/dist/primitives/instance.d.ts +72 -0
  19. package/dist/primitives/instance.js +235 -0
  20. package/dist/primitives/store.d.ts +22 -0
  21. package/dist/primitives/store.js +97 -0
  22. package/dist/provider/backend.d.ts +110 -0
  23. package/dist/provider/backend.js +37 -0
  24. package/dist/provider/interface.d.ts +48 -0
  25. package/dist/provider/interface.js +39 -0
  26. package/dist/reactive/effect.d.ts +11 -0
  27. package/dist/reactive/effect.js +42 -0
  28. package/dist/reactive/index.d.ts +3 -0
  29. package/dist/reactive/index.js +3 -0
  30. package/dist/reactive/signal.d.ts +32 -0
  31. package/dist/reactive/signal.js +60 -0
  32. package/dist/reactive/tracking.d.ts +41 -0
  33. package/dist/reactive/tracking.js +161 -0
  34. package/dist/runtime/fiber.d.ts +21 -0
  35. package/dist/runtime/fiber.js +16 -0
  36. package/dist/runtime/index.d.ts +4 -0
  37. package/dist/runtime/index.js +4 -0
  38. package/dist/runtime/reconcile.d.ts +66 -0
  39. package/dist/runtime/reconcile.js +210 -0
  40. package/dist/runtime/render.d.ts +42 -0
  41. package/dist/runtime/render.js +231 -0
  42. package/dist/runtime/run.d.ts +119 -0
  43. package/dist/runtime/run.js +334 -0
  44. package/dist/runtime/state-machine.d.ts +95 -0
  45. package/dist/runtime/state-machine.js +209 -0
  46. package/dist/types.d.ts +13 -0
  47. package/dist/types.js +4 -0
  48. package/package.json +11 -27
  49. package/dist/cli/commands/BuildCommand.d.ts +0 -40
  50. package/dist/cli/commands/BuildCommand.js +0 -151
  51. package/dist/cli/commands/DeployCommand.d.ts +0 -38
  52. package/dist/cli/commands/DeployCommand.js +0 -194
  53. package/dist/cli/commands/DevCommand.d.ts +0 -52
  54. package/dist/cli/commands/DevCommand.js +0 -394
  55. package/dist/cli/commands/PlanCommand.d.ts +0 -39
  56. package/dist/cli/commands/PlanCommand.js +0 -164
  57. package/dist/cli/commands/index.d.ts +0 -36
  58. package/dist/cli/commands/index.js +0 -43
  59. package/dist/cli/core/ArgumentParser.d.ts +0 -46
  60. package/dist/cli/core/ArgumentParser.js +0 -127
  61. package/dist/cli/core/BaseCommand.d.ts +0 -75
  62. package/dist/cli/core/BaseCommand.js +0 -95
  63. package/dist/cli/core/CLIContext.d.ts +0 -68
  64. package/dist/cli/core/CLIContext.js +0 -183
  65. package/dist/cli/core/CommandRegistry.d.ts +0 -64
  66. package/dist/cli/core/CommandRegistry.js +0 -89
  67. package/dist/cli/core/index.d.ts +0 -36
  68. package/dist/cli/core/index.js +0 -43
  69. package/dist/cli/index.d.ts +0 -35
  70. package/dist/cli/index.js +0 -100
  71. package/dist/cli/output.d.ts +0 -204
  72. package/dist/cli/output.js +0 -437
  73. package/dist/cli/utils.d.ts +0 -59
  74. package/dist/cli/utils.js +0 -76
  75. package/dist/context/createContext.d.ts +0 -90
  76. package/dist/context/createContext.js +0 -113
  77. package/dist/context/index.d.ts +0 -30
  78. package/dist/context/index.js +0 -35
  79. package/dist/core/CReact.d.ts +0 -409
  80. package/dist/core/CReact.js +0 -1151
  81. package/dist/core/CloudDOMBuilder.d.ts +0 -447
  82. package/dist/core/CloudDOMBuilder.js +0 -1234
  83. package/dist/core/ContextDependencyTracker.d.ts +0 -165
  84. package/dist/core/ContextDependencyTracker.js +0 -448
  85. package/dist/core/ErrorRecoveryManager.d.ts +0 -145
  86. package/dist/core/ErrorRecoveryManager.js +0 -443
  87. package/dist/core/EventBus.d.ts +0 -91
  88. package/dist/core/EventBus.js +0 -185
  89. package/dist/core/ProviderOutputTracker.d.ts +0 -211
  90. package/dist/core/ProviderOutputTracker.js +0 -476
  91. package/dist/core/ReactiveUpdateQueue.d.ts +0 -76
  92. package/dist/core/ReactiveUpdateQueue.js +0 -121
  93. package/dist/core/Reconciler.d.ts +0 -415
  94. package/dist/core/Reconciler.js +0 -1044
  95. package/dist/core/RenderScheduler.d.ts +0 -153
  96. package/dist/core/RenderScheduler.js +0 -519
  97. package/dist/core/Renderer.d.ts +0 -336
  98. package/dist/core/Renderer.js +0 -944
  99. package/dist/core/Runtime.d.ts +0 -246
  100. package/dist/core/Runtime.js +0 -640
  101. package/dist/core/StateBindingManager.d.ts +0 -121
  102. package/dist/core/StateBindingManager.js +0 -309
  103. package/dist/core/StateMachine.d.ts +0 -441
  104. package/dist/core/StateMachine.js +0 -883
  105. package/dist/core/StructuralChangeDetector.d.ts +0 -140
  106. package/dist/core/StructuralChangeDetector.js +0 -363
  107. package/dist/core/Validator.d.ts +0 -127
  108. package/dist/core/Validator.js +0 -279
  109. package/dist/core/errors.d.ts +0 -153
  110. package/dist/core/errors.js +0 -202
  111. package/dist/core/index.d.ts +0 -38
  112. package/dist/core/index.js +0 -64
  113. package/dist/core/types.d.ts +0 -265
  114. package/dist/core/types.js +0 -48
  115. package/dist/hooks/context.d.ts +0 -147
  116. package/dist/hooks/context.js +0 -334
  117. package/dist/hooks/useContext.d.ts +0 -113
  118. package/dist/hooks/useContext.js +0 -169
  119. package/dist/hooks/useEffect.d.ts +0 -105
  120. package/dist/hooks/useEffect.js +0 -540
  121. package/dist/hooks/useInstance.d.ts +0 -139
  122. package/dist/hooks/useInstance.js +0 -455
  123. package/dist/hooks/useState.d.ts +0 -120
  124. package/dist/hooks/useState.js +0 -298
  125. package/dist/jsx.d.ts +0 -143
  126. package/dist/jsx.js +0 -76
  127. package/dist/providers/DummyBackendProvider.d.ts +0 -193
  128. package/dist/providers/DummyBackendProvider.js +0 -189
  129. package/dist/providers/DummyCloudProvider.d.ts +0 -128
  130. package/dist/providers/DummyCloudProvider.js +0 -157
  131. package/dist/providers/IBackendProvider.d.ts +0 -177
  132. package/dist/providers/IBackendProvider.js +0 -31
  133. package/dist/providers/ICloudProvider.d.ts +0 -230
  134. package/dist/providers/ICloudProvider.js +0 -31
  135. package/dist/providers/index.d.ts +0 -31
  136. package/dist/providers/index.js +0 -31
  137. package/dist/test-event-callbacks.d.ts +0 -0
  138. package/dist/test-event-callbacks.js +0 -1
  139. package/dist/utils/Logger.d.ts +0 -144
  140. package/dist/utils/Logger.js +0 -220
  141. package/dist/utils/Output.d.ts +0 -161
  142. package/dist/utils/Output.js +0 -401
  143. package/dist/utils/deepEqual.d.ts +0 -71
  144. package/dist/utils/deepEqual.js +0 -276
  145. package/dist/utils/naming.d.ts +0 -241
  146. package/dist/utils/naming.js +0 -376
@@ -1,334 +0,0 @@
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.requireHookContext = requireHookContext;
33
- exports.runWithHookContext = runWithHookContext;
34
- exports.incrementHookIndex = incrementHookIndex;
35
- exports.setRenderContext = setRenderContext;
36
- exports.clearRenderContext = clearRenderContext;
37
- exports.hasRenderContext = hasRenderContext;
38
- exports.getCurrentState = getCurrentState;
39
- exports.pushContextValue = pushContextValue;
40
- exports.popContextValue = popContextValue;
41
- exports.getContextValue = getContextValue;
42
- exports.clearContextStacks = clearContextStacks;
43
- exports.clearPreviousOutputs = clearPreviousOutputs;
44
- exports.setPreviousOutputs = setPreviousOutputs;
45
- exports.getCurrentPath = getCurrentPath;
46
- exports.isRendering = isRendering;
47
- exports.startAccessTracking = startAccessTracking;
48
- exports.endAccessTracking = endAccessTracking;
49
- exports.trackOutputAccess = trackOutputAccess;
50
- exports.getAccessTrackingSession = getAccessTrackingSession;
51
- // Hook context management using AsyncLocalStorage for thread safety
52
- // This ensures hook state is isolated per execution context in concurrent deployments
53
- const async_hooks_1 = require("async_hooks");
54
- /**
55
- * AsyncLocalStorage instance for hook context isolation
56
- */
57
- const hookContextStorage = new async_hooks_1.AsyncLocalStorage();
58
- /**
59
- * Module-level previousOutputsMap that persists across context creations
60
- * This is necessary because runWithHookContext creates fresh contexts,
61
- * but we need to preserve outputs set by setPreviousOutputs() for re-renders
62
- */
63
- let globalPreviousOutputsMap = null;
64
- /**
65
- * Create a new consolidated hook context
66
- */
67
- function createConsolidatedHookContext() {
68
- return {
69
- // Single fiber reference for all hooks
70
- currentFiber: null,
71
- // Separate indices per hook type
72
- stateHookIndex: 0,
73
- effectHookIndex: 0,
74
- contextHookIndex: 0,
75
- instanceHookIndex: 0,
76
- // Context stacks
77
- contextStacks: new Map(),
78
- // useInstance context
79
- currentPath: [],
80
- previousOutputsMap: globalPreviousOutputsMap, // Use global map
81
- // Access tracking
82
- accessTrackingSessions: new Map(),
83
- };
84
- }
85
- /**
86
- * Get the consolidated hook context with validation
87
- * This is the primary function all hooks should use
88
- */
89
- function requireHookContext() {
90
- const context = hookContextStorage.getStore();
91
- if (!context) {
92
- throw new Error('Hook called outside of rendering context. ' +
93
- 'Hooks must be called inside component functions during render.');
94
- }
95
- if (!context.currentFiber) {
96
- throw new Error('Hook called without active fiber context. ' +
97
- 'This indicates a timing issue in the rendering pipeline.');
98
- }
99
- return context;
100
- }
101
- /**
102
- * Get the current hook context, returning null if not available
103
- */
104
- function getHookContextSafe() {
105
- return hookContextStorage.getStore() || null;
106
- }
107
- /**
108
- * Run a function with a new consolidated hook context
109
- */
110
- function runWithHookContext(fn) {
111
- const context = createConsolidatedHookContext();
112
- return hookContextStorage.run(context, fn);
113
- }
114
- /**
115
- * Increment hook index for specific hook type
116
- */
117
- function incrementHookIndex(hookType = 'state') {
118
- const context = requireHookContext();
119
- switch (hookType) {
120
- case 'state':
121
- const stateIndex = context.stateHookIndex;
122
- context.stateHookIndex++;
123
- return stateIndex;
124
- case 'effect':
125
- const effectIndex = context.effectHookIndex;
126
- context.effectHookIndex++;
127
- return effectIndex;
128
- case 'context':
129
- const contextIndex = context.contextHookIndex;
130
- context.contextHookIndex++;
131
- return contextIndex;
132
- case 'instance':
133
- const instanceIndex = context.instanceHookIndex;
134
- context.instanceHookIndex++;
135
- return instanceIndex;
136
- default:
137
- throw new Error(`Unknown hook type: ${hookType}`);
138
- }
139
- }
140
- // ============================================================================
141
- // Render Context Management
142
- // ============================================================================
143
- /**
144
- * Set the current rendering context for all hooks
145
- * Called by Renderer before executing a component
146
- *
147
- * Requirements: 8.2, 8.4
148
- */
149
- function setRenderContext(fiber, path) {
150
- const context = getHookContextSafe();
151
- if (context) {
152
- context.currentFiber = fiber;
153
- context.currentPath = path || [];
154
- context.stateHookIndex = 0;
155
- context.effectHookIndex = 0;
156
- context.contextHookIndex = 0;
157
- context.instanceHookIndex = 0;
158
- }
159
- }
160
- /**
161
- * Clear the current rendering context for all hooks
162
- * Called by Renderer after component execution
163
- *
164
- * Requirements: 8.2, 8.4
165
- */
166
- function clearRenderContext() {
167
- const context = getHookContextSafe();
168
- if (context) {
169
- context.currentFiber = null;
170
- context.stateHookIndex = 0;
171
- context.effectHookIndex = 0;
172
- context.contextHookIndex = 0;
173
- context.instanceHookIndex = 0;
174
- }
175
- }
176
- /**
177
- * Check if there is an active render context
178
- */
179
- function hasRenderContext() {
180
- const context = getHookContextSafe();
181
- return context?.currentFiber !== null;
182
- }
183
- /**
184
- * Get the current fiber state
185
- */
186
- function getCurrentState() {
187
- const context = getHookContextSafe();
188
- return context?.currentFiber?.state;
189
- }
190
- // ============================================================================
191
- // useContext Support Functions
192
- // ============================================================================
193
- /**
194
- * Push a context value onto the stack
195
- * Called by Renderer when entering a Provider
196
- */
197
- function pushContextValue(contextId, value) {
198
- const context = getHookContextSafe();
199
- if (context) {
200
- if (!context.contextStacks.has(contextId)) {
201
- context.contextStacks.set(contextId, []);
202
- }
203
- context.contextStacks.get(contextId).push(value);
204
- }
205
- }
206
- /**
207
- * Pop a context value from the stack
208
- * Called by Renderer when exiting a Provider
209
- */
210
- function popContextValue(contextId) {
211
- const context = getHookContextSafe();
212
- if (context) {
213
- const stack = context.contextStacks.get(contextId);
214
- if (stack && stack.length > 0) {
215
- stack.pop();
216
- }
217
- }
218
- }
219
- /**
220
- * Get the current context value from the stack
221
- */
222
- function getContextValue(contextId) {
223
- const context = getHookContextSafe();
224
- if (!context) {
225
- throw new Error('Hook called outside of rendering context. This is likely a bug in CReact.');
226
- }
227
- const stack = context.contextStacks.get(contextId);
228
- if (stack && stack.length > 0) {
229
- return { hasValue: true, value: stack[stack.length - 1] };
230
- }
231
- return { hasValue: false, value: undefined };
232
- }
233
- /**
234
- * Clear all context stacks
235
- * Called by Renderer to prevent memory leaks
236
- */
237
- function clearContextStacks() {
238
- const context = getHookContextSafe();
239
- if (context) {
240
- context.contextStacks.clear();
241
- }
242
- }
243
- /**
244
- * Clear the global previous outputs map
245
- * Called for test isolation and cleanup
246
- */
247
- function clearPreviousOutputs() {
248
- globalPreviousOutputsMap = null;
249
- const context = getHookContextSafe();
250
- if (context) {
251
- context.previousOutputsMap = null;
252
- }
253
- }
254
- // ============================================================================
255
- // useInstance Support Functions
256
- // ============================================================================
257
- /**
258
- * Set previous outputs map for restoration during render
259
- * Called by CReact before rendering
260
- */
261
- function setPreviousOutputs(outputsMap) {
262
- // Set the global map so it persists across context creations
263
- globalPreviousOutputsMap = outputsMap;
264
- // Also update current context if available
265
- const context = getHookContextSafe();
266
- if (context) {
267
- context.previousOutputsMap = outputsMap;
268
- }
269
- }
270
- /**
271
- * Get the current rendering path
272
- */
273
- function getCurrentPath() {
274
- const context = getHookContextSafe();
275
- if (!context) {
276
- throw new Error('Hook called outside of rendering context. This is likely a bug in CReact.');
277
- }
278
- return [...context.currentPath];
279
- }
280
- /**
281
- * Check if currently rendering
282
- */
283
- function isRendering() {
284
- const context = getHookContextSafe();
285
- return context?.currentFiber !== null;
286
- }
287
- // ============================================================================
288
- // Access Tracking for Output Dependency Analysis
289
- // ============================================================================
290
- /**
291
- * Start tracking output accesses for a fiber
292
- * Used by useEffect to track which outputs are accessed in dependencies
293
- */
294
- function startAccessTracking(fiber) {
295
- const context = requireHookContext();
296
- context.accessTrackingSessions.set(fiber, {
297
- fiber,
298
- startTime: Date.now(),
299
- trackedOutputs: new Set(),
300
- isActive: true,
301
- });
302
- }
303
- /**
304
- * End tracking and return the set of accessed outputs
305
- */
306
- function endAccessTracking(fiber) {
307
- const context = requireHookContext();
308
- const session = context.accessTrackingSessions.get(fiber);
309
- if (!session) {
310
- return new Set();
311
- }
312
- session.isActive = false;
313
- context.accessTrackingSessions.delete(fiber);
314
- return session.trackedOutputs;
315
- }
316
- /**
317
- * Track an output access during an active tracking session
318
- */
319
- function trackOutputAccess(fiber, bindingKey) {
320
- const context = getHookContextSafe();
321
- if (!context)
322
- return;
323
- const session = context.accessTrackingSessions.get(fiber);
324
- if (session?.isActive) {
325
- session.trackedOutputs.add(bindingKey);
326
- }
327
- }
328
- /**
329
- * Get the current access tracking session for a fiber
330
- */
331
- function getAccessTrackingSession(fiber) {
332
- const context = getHookContextSafe();
333
- return context?.accessTrackingSessions.get(fiber);
334
- }
@@ -1,113 +0,0 @@
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 { Context } from '../context/createContext';
31
- import { FiberNode } from '../core/types';
32
- /**
33
- * Set the context dependency tracker instance
34
- * Called by CReact during initialization
35
- *
36
- * @internal
37
- */
38
- export declare function setContextDependencyTracker(tracker: any): void;
39
- /**
40
- * Get the context dependency tracker instance
41
- *
42
- * @internal
43
- */
44
- export declare function getContextDependencyTracker(): any;
45
- /**
46
- * Set the current rendering context for useContext
47
- * Called by Renderer before executing a component
48
- *
49
- * @internal
50
- */
51
- export declare function setContextRenderContext(fiber: FiberNode): void;
52
- /**
53
- * Clear the current rendering context for useContext
54
- * Called by Renderer after component execution
55
- *
56
- * @internal
57
- */
58
- export declare function clearContextRenderContext(): void;
59
- /**
60
- * Push a context value onto the stack
61
- * Called by Renderer when entering a Provider
62
- *
63
- * @internal
64
- */
65
- export declare function pushContextValue(contextId: symbol, value: any): void;
66
- /**
67
- * Pop a context value from the stack
68
- * Called by Renderer when exiting a Provider
69
- *
70
- * @internal
71
- */
72
- export declare function popContextValue(contextId: symbol): void;
73
- /**
74
- * Clear all context stacks
75
- * Called by Renderer to prevent memory leaks
76
- *
77
- * @internal
78
- */
79
- export declare function clearContextStacks(): void;
80
- /**
81
- * useContext hook - Retrieve value from nearest Provider (like React.useContext)
82
- *
83
- * This hook retrieves the value from the nearest Provider in the component tree.
84
- * The Renderer maintains a stack of context values as it traverses the tree.
85
- *
86
- * Enhanced with reactive capabilities:
87
- * - Tracks context dependencies for selective re-rendering
88
- * - Only triggers re-renders when context values are bound to provider outputs
89
- * - Integrates with ContextDependencyTracker for change detection
90
- *
91
- * REQ-02: Stack Context (declarative outputs)
92
- * REQ-3.1, 3.2, 3.3, 3.4, 3.5: Context reactivity system
93
- *
94
- * @param context - Context object created by createContext
95
- * @returns Value from nearest Provider, or default value if no Provider found
96
- * @throws Error if no Provider found and no default value provided
97
- *
98
- * @example
99
- * ```tsx
100
- * const RegistryContext = createContext<{ repositoryUrl?: string }>({});
101
- *
102
- * function Service() {
103
- * const { repositoryUrl } = useContext(RegistryContext);
104
- *
105
- * const service = useInstance(AppRunnerService, {
106
- * image: `${repositoryUrl}:latest`
107
- * });
108
- *
109
- * return <></>;
110
- * }
111
- * ```
112
- */
113
- export declare function useContext<T>(context: Context<T>): T;
@@ -1,169 +0,0 @@
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.setContextDependencyTracker = setContextDependencyTracker;
33
- exports.getContextDependencyTracker = getContextDependencyTracker;
34
- exports.setContextRenderContext = setContextRenderContext;
35
- exports.clearContextRenderContext = clearContextRenderContext;
36
- exports.pushContextValue = pushContextValue;
37
- exports.popContextValue = popContextValue;
38
- exports.clearContextStacks = clearContextStacks;
39
- exports.useContext = useContext;
40
- const context_1 = require("./context");
41
- // Global context dependency tracker instance
42
- let contextDependencyTracker = null;
43
- /**
44
- * Set the context dependency tracker instance
45
- * Called by CReact during initialization
46
- *
47
- * @internal
48
- */
49
- function setContextDependencyTracker(tracker) {
50
- contextDependencyTracker = tracker;
51
- }
52
- /**
53
- * Get the context dependency tracker instance
54
- *
55
- * @internal
56
- */
57
- function getContextDependencyTracker() {
58
- return contextDependencyTracker;
59
- }
60
- /**
61
- * Set the current rendering context for useContext
62
- * Called by Renderer before executing a component
63
- *
64
- * @internal
65
- */
66
- function setContextRenderContext(fiber) {
67
- (0, context_1.setRenderContext)(fiber);
68
- }
69
- /**
70
- * Clear the current rendering context for useContext
71
- * Called by Renderer after component execution
72
- *
73
- * @internal
74
- */
75
- function clearContextRenderContext() {
76
- (0, context_1.clearRenderContext)();
77
- }
78
- /**
79
- * Push a context value onto the stack
80
- * Called by Renderer when entering a Provider
81
- *
82
- * @internal
83
- */
84
- function pushContextValue(contextId, value) {
85
- (0, context_1.pushContextValue)(contextId, value);
86
- }
87
- /**
88
- * Pop a context value from the stack
89
- * Called by Renderer when exiting a Provider
90
- *
91
- * @internal
92
- */
93
- function popContextValue(contextId) {
94
- (0, context_1.popContextValue)(contextId);
95
- }
96
- /**
97
- * Clear all context stacks
98
- * Called by Renderer to prevent memory leaks
99
- *
100
- * @internal
101
- */
102
- function clearContextStacks() {
103
- (0, context_1.clearContextStacks)();
104
- }
105
- /**
106
- * useContext hook - Retrieve value from nearest Provider (like React.useContext)
107
- *
108
- * This hook retrieves the value from the nearest Provider in the component tree.
109
- * The Renderer maintains a stack of context values as it traverses the tree.
110
- *
111
- * Enhanced with reactive capabilities:
112
- * - Tracks context dependencies for selective re-rendering
113
- * - Only triggers re-renders when context values are bound to provider outputs
114
- * - Integrates with ContextDependencyTracker for change detection
115
- *
116
- * REQ-02: Stack Context (declarative outputs)
117
- * REQ-3.1, 3.2, 3.3, 3.4, 3.5: Context reactivity system
118
- *
119
- * @param context - Context object created by createContext
120
- * @returns Value from nearest Provider, or default value if no Provider found
121
- * @throws Error if no Provider found and no default value provided
122
- *
123
- * @example
124
- * ```tsx
125
- * const RegistryContext = createContext<{ repositoryUrl?: string }>({});
126
- *
127
- * function Service() {
128
- * const { repositoryUrl } = useContext(RegistryContext);
129
- *
130
- * const service = useInstance(AppRunnerService, {
131
- * image: `${repositoryUrl}:latest`
132
- * });
133
- *
134
- * return <></>;
135
- * }
136
- * ```
137
- */
138
- function useContext(context) {
139
- // Use consolidated hook context
140
- const hookContext = (0, context_1.requireHookContext)();
141
- const currentFiber = hookContext.currentFiber; // Non-null assertion safe due to requireHookContext validation
142
- // Get hook index for dependency tracking (context-specific)
143
- const hookIndex = (0, context_1.incrementHookIndex)('context');
144
- // Track context dependency for reactive updates
145
- if (contextDependencyTracker) {
146
- contextDependencyTracker.trackContextConsumption(context._contextId, currentFiber, hookIndex);
147
- }
148
- // Look up the context value from the stack
149
- const result = (0, context_1.getContextValue)(context._contextId);
150
- let contextValue;
151
- // If Provider found, return the value (even if it's undefined)
152
- if (result.hasValue) {
153
- contextValue = result.value;
154
- }
155
- else if (context.defaultValue !== undefined) {
156
- // If no Provider found, use default value
157
- contextValue = context.defaultValue;
158
- }
159
- else {
160
- // No Provider and no default value - throw error
161
- throw new Error(`useContext called without a Provider for this context and no default value was provided. ` +
162
- `Make sure to wrap your component tree with <Context.Provider value={...}>.`);
163
- }
164
- // Store the context value in the dependency tracker for change detection
165
- if (contextDependencyTracker) {
166
- contextDependencyTracker.setInitialContextValue(context._contextId, contextValue);
167
- }
168
- return contextValue;
169
- }