casper-context 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 (44) hide show
  1. package/README.md +253 -0
  2. package/dist/index.js +9 -0
  3. package/dist/lifecycle/post.js +239 -0
  4. package/dist/lifecycle/pre.js +113 -0
  5. package/dist/plugin.js +57 -0
  6. package/dist/transforms/autoContextTransform.js +1 -0
  7. package/dist/transforms/contextTransform.js +1 -0
  8. package/dist/transforms/stateTransform.js +1 -0
  9. package/dist/types/plugin.d.js +1 -0
  10. package/dist/utils/astHelpers.js +644 -0
  11. package/dist/utils/constants.js +111 -0
  12. package/dist/utils/names.js +1 -0
  13. package/dist/utils/scope.js +1 -0
  14. package/dist/utils/utilityHelpers.js +606 -0
  15. package/dist/visitors/AssignmentExpression.js +104 -0
  16. package/dist/visitors/CallExpression.js +1 -0
  17. package/dist/visitors/FunctionDeclaration.js +116 -0
  18. package/dist/visitors/Identifier.js +123 -0
  19. package/dist/visitors/JSXElement.js +1 -0
  20. package/dist/visitors/Program.js +278 -0
  21. package/dist/visitors/ReturnStatement.js +81 -0
  22. package/dist/visitors/VariableDeclaration.js +209 -0
  23. package/package.json +60 -0
  24. package/src/index.js +2 -0
  25. package/src/lifecycle/post.js +237 -0
  26. package/src/lifecycle/pre.js +103 -0
  27. package/src/plugin.js +51 -0
  28. package/src/transforms/autoContextTransform.js +0 -0
  29. package/src/transforms/contextTransform.js +0 -0
  30. package/src/transforms/stateTransform.js +0 -0
  31. package/src/types/plugin.d.ts +0 -0
  32. package/src/utils/astHelpers.js +767 -0
  33. package/src/utils/constants.js +102 -0
  34. package/src/utils/names.js +0 -0
  35. package/src/utils/scope.js +0 -0
  36. package/src/utils/utilityHelpers.js +636 -0
  37. package/src/visitors/AssignmentExpression.js +100 -0
  38. package/src/visitors/CallExpression.js +0 -0
  39. package/src/visitors/FunctionDeclaration.js +114 -0
  40. package/src/visitors/Identifier.js +142 -0
  41. package/src/visitors/JSXElement.js +0 -0
  42. package/src/visitors/Program.js +280 -0
  43. package/src/visitors/ReturnStatement.js +75 -0
  44. package/src/visitors/VariableDeclaration.js +216 -0
package/README.md ADDED
@@ -0,0 +1,253 @@
1
+ <!--lint disable awesome-heading awesome-github awesome-toc double-link -->
2
+
3
+ <p align="center">
4
+ <br>
5
+ <img width="400" src="./react-casper-context.png" alt="react casper context logo">
6
+ <br><br>
7
+ </p>
8
+
9
+ <h1 align="center">React Casper Context</h1>
10
+
11
+ <h3 align="center">
12
+ 🚀 Declare it like a normal JavaScript variable. Use it anywhere like React Context.
13
+ </h3>
14
+
15
+ <p align="center">
16
+ Casper Context is a Babel compile-time plugin that transforms specially prefixed variables into fully functional React Context API state — automatically.
17
+ <br/>
18
+ No providers. No boilerplate. No complex setup.
19
+ <br/>
20
+ Just declare → use → update.
21
+ </p>
22
+
23
+ <p align="center">
24
+ <a href="https://chic-duckanoo-aa0a41.netlify.app/">
25
+ <img src="https://img.shields.io/badge/Live%20Demo-Open-green?style=for-the-badge" />
26
+ </a>
27
+ </p>
28
+
29
+ <!--lint ignore-->
30
+
31
+ ## ✨ Quick Example
32
+ ### ✅ Declare Context Variable
33
+
34
+ ```jsx
35
+ import React from 'react'
36
+
37
+ function App() {
38
+
39
+ let _$_appMessage = 'Say Hi to the Casper';
40
+
41
+ return (
42
+ <>
43
+ <CasperHero />
44
+ <MessageBox />
45
+ </>
46
+ );
47
+ }
48
+ ```
49
+
50
+ ### ✅ Use Anywhere In Component Tree
51
+
52
+ ```jsx
53
+ import React from 'react'
54
+
55
+ function CasperHero() {
56
+
57
+ return <h1>{_$_appMessage}</h1>;
58
+
59
+ }
60
+
61
+ ```
62
+
63
+ ### ✅ Update Like Normal Variable
64
+
65
+ ```jsx
66
+ import React from 'react';
67
+
68
+ function MessageBox() {
69
+
70
+ const handleChange = () => {
71
+ _$_appMessage = 'Hi Casper';
72
+ }
73
+
74
+ return (
75
+ <>
76
+
77
+ <button onClick={handleChange}>
78
+ Change
79
+ </button>
80
+
81
+ </>;
82
+ }
83
+ ```
84
+
85
+ That’s it. Under the hood, the plugin rewrites your code to use the native React Context API. It is 100% React-compliant at runtime.
86
+
87
+ ### ✨ Features
88
+
89
+ - **Zero Boilerplate:** No more createContext, useContext, or wrapping components manually.
90
+ - **Automatic Reactivity:** When a casper variable changes, all components using it re-render automatically..
91
+ - **Scoped & Global:** Accessible in the component where it's declared and any nested child component.
92
+ - **Native Performance:** Since it compiles to the native React Context API, there is zero overhead compared to writing Context manually.
93
+ - **Standard Syntax:** Use familiar assignment syntax to update global state.
94
+
95
+ ### 📦 Installation
96
+
97
+ ```bash
98
+ npm install casper-context --save-dev
99
+ ```
100
+ ### ⚙️ Setup
101
+
102
+ #### 1️⃣ Add Babel Plugin
103
+ Add it to your `.babelrc` or `babel.config.js`
104
+
105
+ ```json
106
+ {
107
+ "plugins": ["casper-context"]
108
+ }
109
+ ```
110
+ #### 2️⃣ CRA Users (Important)
111
+ Create React App does not support direct Babel modification. You must use CRACO.
112
+
113
+ Install CRACO:
114
+
115
+ ```bash
116
+ npm install @craco/craco
117
+ ```
118
+ Then configure CRACO to inject the Casper Context Babel plugin in package.json
119
+
120
+ ```json
121
+ "scripts": {
122
+ "start": "craco start",
123
+ "build": "craco build",
124
+ "test": "craco test",
125
+ "eject": "react-scripts eject"
126
+ }
127
+ ```
128
+ #### 3️⃣ ESLint Setup (Required)
129
+ To avoid `undefined` variable warnings
130
+ ```js
131
+ globals: {
132
+ ...require('./casper-eslint.global.js')
133
+ }
134
+ ```
135
+
136
+ ### 🔧 Custom Configuration
137
+
138
+ By default, the plugin identifies variables using the `_$_` prefix.
139
+
140
+ ```javascript
141
+ // Default usage
142
+ let _$_myName = 'Jhone';
143
+ ```
144
+ ###### Custom Prefix
145
+ If you encounter naming collisions or simply prefer a different identifier, you can customize the prefix. Create a `.casperctxrc.json` file in your **project root** and specify your preferred prefix
146
+ ```json
147
+ {
148
+ "prefix": "CCTX"
149
+ }
150
+ ```
151
+ Now, the plugin will look for your custom string instead
152
+ ```jsx
153
+ // With custom configuration
154
+ let CCTXmyName = 'Jhone';
155
+ ```
156
+
157
+ ## 📜 The Golden Rules
158
+
159
+ To ensure Casper Context transforms your code correctly, please follow these core principles:
160
+
161
+ ### 1. Naming & Prefix
162
+ Every Casper variable **must** start with the defined prefix (Default: `_$_`).
163
+ * **Correct:** `let _$_userName = 'John';`
164
+ * **Incorrect:** `let userName = 'John';`
165
+
166
+ ### 2. React Import Requirement
167
+ Any file that declares, reads, or writes a Casper variable **must** import React. This is required because the compiled code relies on `React.useContext` and `React.useState`.
168
+ * Any valid import works:
169
+ * `import React from 'react';`
170
+ * `import * as React from 'react';`
171
+
172
+ ### 3. Follow React Hook Rules
173
+ Since Casper variables are converted into Hooks under the hood, they must follow the [Rules of Hooks](https://react.dev/warnings/rules-of-hooks):
174
+ * Only declare variables at the **top level** of your React function component.
175
+ * Do **not** declare them inside loops, conditions, or nested functions.
176
+
177
+ ### 4. Global Uniqueness (Naming)
178
+ Currently, Casper variables are treated as globally unique identifiers. You must ensure that every Casper variable name is unique across your entire project, even if they are in different components.
179
+ * **Example:** If you have `_$_user` in `ComponentA`, do not use `_$_user` in `ComponentB`. Use `_$_adminUser` or `_$_customerUser` instead.
180
+
181
+ ### 5. Component-Based Context Grouping
182
+ Contexts are grouped by the component where the variables are declared.
183
+ * All `_$_` variables declared in the **same component** share the **same Context**.
184
+ * To create **separate Contexts**, declare your variables in **different components**.
185
+
186
+
187
+
188
+ #### Example:
189
+ **Context A (Admin Scope):**
190
+ ```javascript
191
+ function Admin() {
192
+ let _$_adminName = 'Jakie';
193
+ let _$_adminAge = 34;
194
+ // These belong to the 'Admin' Context
195
+ }
196
+ ```
197
+ **Context B (Customer Scope):**
198
+ ```javascript
199
+ function Customer() {
200
+ let _$_customerName = 'Scot';
201
+ let _$_customerAge = 25;
202
+ // These belong to the 'Customer' Context
203
+ }
204
+ ```
205
+
206
+ ## 🛠 Troubleshooting
207
+
208
+ If your variables are not becoming reactive or you see errors in the console, check the following:
209
+
210
+ ### 1. Variables are not transforming
211
+ * **Check the Prefix**: Ensure your variable starts exactly with your prefix (Default: `_$_`).
212
+ * **Declaration Keyword**: Use `let` or `var` for variables you intend to update. Using `const` will prevent you from reassigning the value later.
213
+ * **Babel Cache**: Babel often caches transforms. Try restarting your dev server or clearing the cache (e.g., `rm -rf node_modules/.cache`).
214
+
215
+ ### 2. "Variable is not defined" (ESLint Errors)
216
+ Because Casper Context injects variables at compile-time, ESLint might think they are undefined.
217
+ * **Solution**: The plugin automatically generates a `casper-eslint.global.js` file in your root. Reference this in your `.eslintrc.js`:
218
+ ```javascript
219
+ const casperGlobals = require('./casper-eslint.global.js');
220
+ module.exports = {
221
+ globals: { ...casperGlobals }
222
+ };
223
+ ### 3. Changes to `.casperctxrc.json` not reflecting
224
+ Babel reads the configuration once when the process starts.
225
+ * **Solution**: If you change your custom prefix in `.casperctxrc.json`, you **must restart** your build tool (Vite, Webpack, or Next.js).
226
+ ### 4. Component not re-rendering
227
+ * **Scope**: Ensure the variable is declared within a React Component or a file that is part of the Babel transformation path.
228
+
229
+ * **Hooks Rules**: Remember that under the hood, this becomes a React Hook. Do not declare `_$_` variables inside nested loops or conditional if statements.
230
+ ## 📝 Debugging
231
+ If you are still having trouble, enable debug mode in your `.casperctxrc.json`
232
+ ```json
233
+ {
234
+ "prefix": "_$_",
235
+ "debug": true,
236
+ "debug_levels": ['reset','info','warn','error', 'debug', 'trace']
237
+ }
238
+ ```
239
+ This will generate a `.casperctx.debug.log` file in your project root, detailing exactly how the plugin is mapping your variables.
240
+
241
+ ### 🗺 Roadmap
242
+ - ✅ CRA Support
243
+ - ✅ Babel + Webpack Support
244
+ - 🚧 Vite Integration
245
+ - 🚧 Next.js Integration
246
+ - 🚧 TypeScript Improvements
247
+ - 🚧 Developer Tools Integration
248
+
249
+ ### 🤝 Contributing
250
+ Contributions, suggestions, and issues are welcome.
251
+
252
+ ### 📜 License
253
+ MIT License
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _plugin = _interopRequireDefault(require("./plugin"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ var _default = exports.default = _plugin.default;
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = postProcess;
7
+ var _fs = _interopRequireDefault(require("fs"));
8
+ var _path = _interopRequireDefault(require("path"));
9
+ var _utilityHelpers = require("../utils/utilityHelpers");
10
+ var _constants = require("../utils/constants");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ /**
13
+ * @fileoverview Environment Initialization and File Orchestration.
14
+ * This module is responsible for the physical creation and synchronization of
15
+ * the Casper Context infrastructure, including the global context bridge and
16
+ * ESLint configuration overrides.
17
+ */
18
+
19
+ /**
20
+ * Path Utilities & Constants
21
+ * @description Leverages resolved system paths and core constants to ensure
22
+ * write operations target the correct project directories.
23
+ */
24
+
25
+ /**
26
+ * @module Logger
27
+ * @description Provides a controlled logging interface for the Babel transformation process.
28
+ */
29
+
30
+ /**
31
+ * @important
32
+ * The following imports are critical for the library's lifecycle:
33
+ * - `CONTEXT_FILE_PATH`: The destination for the auto-generated React Context logic.
34
+ * - `ESLINT_GLOBAL_JS_PATH`: The file that prevents 'no-undef' errors for _$_ variables.
35
+ * - `UNICODE_UTF8`: Standard encoding used for all `fs.writeFileSync` operations.
36
+ */
37
+
38
+ /**
39
+ * Generates a JavaScript module file that exports React context instances
40
+ * based on the registered variables in the `virtualRegistry`.
41
+ *
42
+ * This function creates or overwrites the file at `CONTEXT_FILE_PATH`, injecting
43
+ * `'use strict'` directives, ES module compatibility boilerplate, and context
44
+ * initialization code. Each registered component context is turned into a
45
+ * `React.createContext` with default values derived from the registry.
46
+ *
47
+ * @param {Object<string, Object>} virtualRegistry - The in-memory registry mapping
48
+ * component hashes to their context metadata:
49
+ * ```js
50
+ * {
51
+ * [componentHash]: {
52
+ * ctxName: string, // Generated context name
53
+ * varNames: string[], // List of variable names registered for this context
54
+ * defaults: Record<string, any> // Default values for each variable
55
+ * }
56
+ * }
57
+ * ```
58
+ *
59
+ * @returns {void}
60
+ * This function writes to the filesystem directly and does not return a value.
61
+ *
62
+ * @important
63
+ * - The generated module follows CommonJS export style with ES module compatibility.
64
+ * - All variables registered in `virtualRegistry` are included in their respective
65
+ * `createContext` objects. Variables without a default value are set to `_CCTX_UNDEFINED`.
66
+ * - The function overwrites any existing file at `CONTEXT_FILE_PATH`.
67
+ * - React is imported as `_react` and used for `createContext` calls.
68
+ * - The `_CCTX_CMP_NAME_PREFIX` is stripped from exported context names for clarity.
69
+ * - Errors are silently caught; consider adding logging for debugging or dev builds.
70
+ * - The generated content is formatted with line breaks and indentation for readability.
71
+ *
72
+ * @example
73
+ * ```js
74
+ * const virtualRegistry = {
75
+ * 'abc123': {
76
+ * ctxName: '_CCTX_abc123',
77
+ * varNames: ['count', 'enabled'],
78
+ * defaults: { count: 0, enabled: true }
79
+ * }
80
+ * };
81
+ * generateContextContent(virtualRegistry);
82
+ * // Produces a file exporting a React context with default { count: 0, enabled: true }
83
+ * ```
84
+ */
85
+ function generateContextContent(virtualRegistry) {
86
+ try {
87
+ _fs.default.writeFileSync(_utilityHelpers.CONTEXT_FILE_PATH, _constants._CCTX_EMPTY, _constants.UNICODE_UTF8);
88
+ let contextNames = [];
89
+ let content = `'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n`;
90
+ if (Object.keys(virtualRegistry).length === 0) return;
91
+ Object.values(virtualRegistry).forEach(entry => {
92
+ if (!entry.ctxName) return;
93
+ contextNames.push(entry.ctxName.replace(_constants._CCTX_CMP_NAME_PREFIX, _constants._CCTX_EMPTY));
94
+ });
95
+ content += `exports.${contextNames.join(' = exports.')} = void 0;\n`;
96
+ content += `var _react = require('react');\n`;
97
+ Object.values(virtualRegistry).forEach(entry => {
98
+ if (!entry.ctxName) return;
99
+ const {
100
+ ctxName,
101
+ varNames,
102
+ defaults
103
+ } = entry;
104
+ const defaultObjProps = varNames.map(name => {
105
+ const val = defaults[name] !== undefined ? JSON.stringify(defaults[name]) : _constants._CCTX_UNDEFINED;
106
+ return ` ${name}: ${val}`;
107
+ }).join(',\n');
108
+ content += `const ${ctxName.replace(_constants._CCTX_CMP_NAME_PREFIX, _constants._CCTX_EMPTY)} = exports.${ctxName.replace(_constants._CCTX_CMP_NAME_PREFIX, _constants._CCTX_EMPTY)} = /*#__PURE__*/(0, _react.createContext)({\n${defaultObjProps}\n});\n`;
109
+ });
110
+ _fs.default.writeFileSync(_utilityHelpers.CONTEXT_FILE_PATH, content, _constants.UNICODE_UTF8);
111
+ } catch (e) {
112
+ (0, _utilityHelpers.log)('error', '[::generateContextContent::]', e.message);
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Generates or updates the ESLint global variables configuration file
118
+ * based on the current virtual registry.
119
+ *
120
+ * This function reads all variable names registered in `virtualRegistry`
121
+ * and writes them as read-only globals in a JavaScript module (`ESLINT_GLOBAL_JS_PATH`).
122
+ * It compares the newly generated content with the existing file and only
123
+ * overwrites if changes are detected. Finally, it updates the modification
124
+ * timestamp of the ESLint configuration file to trigger linting updates if needed.
125
+ *
126
+ * @param {Object<string, Object>} virtualRegistry - The in-memory registry of component
127
+ * variables. Each entry should contain:
128
+ * ```js
129
+ * {
130
+ * varNames: string[], // List of variable names for the component/context
131
+ * ctxName?: string, // Optional context name
132
+ * defaults?: Record<string, any> // Optional default values
133
+ * }
134
+ * ```
135
+ * @param {Object<string, Object>} [prevVirtualRegistrySnap] - Optional snapshot of
136
+ * the previous virtual registry state. Currently unused, but can be used
137
+ * to detect changes or optimize writes.
138
+ *
139
+ * @returns {void}
140
+ * Writes or updates the ESLint global JS file on disk and updates the
141
+ * corresponding ESLint configuration file's timestamps.
142
+ *
143
+ * @important
144
+ * - All variables are marked as read-only in the ESLint globals (`CASPER_READ_ONLY_TYPE`).
145
+ * - File writes are **atomic**: the target file is cleared before writing new content.
146
+ * - If no variables exist in the registry, the function exits early without writing.
147
+ * - Errors are silently caught; consider adding logging for development.
148
+ * - Changes are only applied if the content differs from the current file, avoiding
149
+ * unnecessary filesystem writes.
150
+ * - The file starts with a comment indicating it is auto-generated by CasperContext.
151
+ *
152
+ * @example
153
+ * ```js
154
+ * const virtualRegistry = {
155
+ * 'abc123': {
156
+ * varNames: ['count', 'enabled'],
157
+ * ctxName: '_CCTX_abc123',
158
+ * defaults: { count: 0, enabled: true }
159
+ * }
160
+ * };
161
+ * generateLintGlobalJS(virtualRegistry);
162
+ * // Writes ESLint globals file:
163
+ * // module.exports = {
164
+ * // "count": "readonly",
165
+ * // "enabled": "readonly"
166
+ * // };
167
+ * ```
168
+ */
169
+ function generateLintGlobalJS(virtualRegistry, prevVirtualRegistrySnap) {
170
+ try {
171
+ if (Object.keys(virtualRegistry).length === 0) return;
172
+ const currentCnt = _fs.default.readFileSync(_utilityHelpers.ESLINT_GLOBAL_JS_PATH, _constants.UNICODE_UTF8);
173
+ const content = Object.values(virtualRegistry).flatMap(entry => entry.varNames || []).map(name => ` "${name}": "${_constants.CASPER_READ_ONLY_TYPE}"`).join(',\n');
174
+ const fileContent = `// ****** generated by CasperContext ******
175
+ module.exports = {\n${content}\n};\n`;
176
+ if (currentCnt !== fileContent) {
177
+ _fs.default.writeFileSync(_utilityHelpers.ESLINT_GLOBAL_JS_PATH, _constants._CCTX_EMPTY, _constants.UNICODE_UTF8);
178
+ _fs.default.writeFileSync(_utilityHelpers.ESLINT_GLOBAL_JS_PATH, fileContent, _constants.UNICODE_UTF8);
179
+ _fs.default.utimesSync(_path.default.join(process.cwd(), _constants.ESLINT_RC_FILE), new Date(), new Date());
180
+ }
181
+ } catch (e) {
182
+ (0, _utilityHelpers.log)('error', '[::generateLintGlobalJS::]', e.message);
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Performs post-processing steps after AST transformations on a file.
188
+ *
189
+ * This function generates or updates auxiliary files based on the current
190
+ * state of the virtual registry. Specifically:
191
+ * 1. `generateContextContent` – creates the module exporting React context
192
+ * instances with default values.
193
+ * 2. `generateLintGlobalJS` – updates the ESLint global variables file
194
+ * with read-only entries for all registered variables.
195
+ *
196
+ * @param {string} file - The path of the file that was processed. Currently unused,
197
+ * but provided for future enhancements or logging purposes.
198
+ * @param {Object} t - Babel types helper (`@babel/types`) used in AST operations.
199
+ * @param {Object<string, Object>} virtualRegistry - The in-memory registry
200
+ * of component/context variables, structured as:
201
+ * ```js
202
+ * {
203
+ * [componentHash]: {
204
+ * ctxName: string,
205
+ * varNames: string[],
206
+ * defaults: Record<string, any>
207
+ * }
208
+ * }
209
+ * ```
210
+ * @param {Object<string, Object>} [prevVirtualRegistrySnap] - Optional snapshot
211
+ * of the previous virtual registry state, used to detect changes and optimize writes.
212
+ *
213
+ * @returns {void}
214
+ * This function does not return a value; its effect is to update filesystem
215
+ * files (`CONTEXT_FILE_PATH` and `ESLINT_GLOBAL_JS_PATH`) based on the registry.
216
+ *
217
+ * @important
218
+ * - Errors are silently caught; consider adding logging for debugging.
219
+ * - Both `generateContextContent` and `generateLintGlobalJS` may overwrite
220
+ * existing files.
221
+ * - The `file` parameter is not currently used internally but is included
222
+ * for potential future processing logic.
223
+ *
224
+ * @example
225
+ * ```js
226
+ * import postProcess from './postProcess';
227
+ *
228
+ * postProcess('src/App.js', t, virtualRegistry, prevVirtualRegistrySnap);
229
+ * // Generates context and ESLint globals files based on the current registry
230
+ * ```
231
+ */
232
+ function postProcess(file, t, virtualRegistry, prevVirtualRegistrySnap) {
233
+ try {
234
+ generateContextContent(virtualRegistry);
235
+ generateLintGlobalJS(virtualRegistry, prevVirtualRegistrySnap);
236
+ } catch (e) {
237
+ (0, _utilityHelpers.log)('error', '[::postProcess::]', e.message);
238
+ }
239
+ }
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = preProcess;
7
+ var _fs = _interopRequireDefault(require("fs"));
8
+ var _path = _interopRequireDefault(require("path"));
9
+ var _utilityHelpers = require("../utils/utilityHelpers");
10
+ var _constants = require("../utils/constants");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ /**
13
+ * @fileoverview File System Orchestration for Casper Context.
14
+ * This module manages the lifecycle of the generated context files, handling
15
+ * the reading, writing, and directory verification required to sync the
16
+ * Babel transformation with the physical project structure.
17
+ */
18
+
19
+ /**
20
+ * Path & State Dependencies
21
+ * @description
22
+ * - CONTEXT_FILE_PATH: The absolute resolved destination for the generated React Context.
23
+ * - _CCTX_EMPTY: Used as a safe fallback or initializer for file content buffers.
24
+ */
25
+
26
+ /**
27
+ * @module Logger
28
+ * @description Provides a controlled logging interface for the Babel transformation process.
29
+ */
30
+
31
+ /**
32
+ * @important
33
+ * All file operations in this module should prioritize synchronous methods (`fs.writeFileSync`, etc.)
34
+ * during the Babel build-step to ensure the file system is in sync before the
35
+ * bundling process (Webpack/Vite) begins.
36
+ */
37
+
38
+ /**
39
+ * Initializes the scope context file and directory for Casper context tracking.
40
+ *
41
+ * This function ensures that the directory containing the context file exists,
42
+ * and then creates an empty context file at `CONTEXT_FILE_PATH` if it does not
43
+ * already exist. It is intended to prepare the filesystem for storing generated
44
+ * React context instances and related metadata.
45
+ *
46
+ * @returns {void}
47
+ * This function does not return a value; its effect is purely filesystem-based.
48
+ *
49
+ * @important
50
+ * - Uses `fs.mkdirSync` with `{ recursive: true }` to create parent directories as needed.
51
+ * - Writes an empty file at `CONTEXT_FILE_PATH` with the `{ flag: 'wx' }` option,
52
+ * which means the file is only created if it does not already exist.
53
+ * - Errors are silently caught, so existing files or directories will not cause failures.
54
+ * - Intended to be called before processing files (`preProcess`) or generating context content.
55
+ *
56
+ * @example
57
+ * ```js
58
+ * createScopeContext();
59
+ * // Ensures the context directory and empty context file exist
60
+ * ```
61
+ */
62
+ function createScopeContext() {
63
+ try {
64
+ const dirPath = _path.default.dirname(_utilityHelpers.CONTEXT_FILE_PATH);
65
+ _fs.default.mkdirSync(dirPath, {
66
+ recursive: true
67
+ });
68
+ _fs.default.writeFileSync(_utilityHelpers.CONTEXT_FILE_PATH, _constants._CCTX_EMPTY, {
69
+ flag: 'wx'
70
+ });
71
+ } catch (e) {
72
+ (0, _utilityHelpers.log)('error', '[::createScopeContext::]', e.message);
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Performs pre-processing steps before AST transformations on a file.
78
+ *
79
+ * This function sets up the necessary runtime or plugin context before
80
+ * any file transformations occur. Currently, it calls `createScopeContext()`
81
+ * to initialize the global scope or virtual registry for tracking component
82
+ * variables and contexts.
83
+ *
84
+ * @param {string} file - The path of the file that will be processed. Currently unused,
85
+ * but provided for future enhancements or logging purposes.
86
+ * @param {Object} t - Babel types helper (`@babel/types`) used for AST operations.
87
+ *
88
+ * @returns {void}
89
+ * This function does not return a value; its effect is to initialize internal
90
+ * context structures for later processing.
91
+ *
92
+ * @important
93
+ * - Errors are silently caught; consider adding logging for debugging.
94
+ * - Currently, the function only calls `createScopeContext()`, but can be
95
+ * extended for additional pre-processing tasks.
96
+ * - The `file` parameter is not used internally but may be relevant in
97
+ * future versions for file-specific setup.
98
+ *
99
+ * @example
100
+ * ```js
101
+ * import preProcess from './preProcess';
102
+ *
103
+ * preProcess('src/App.js', t);
104
+ * // Initializes context for virtual registry and component tracking
105
+ * ```
106
+ */
107
+ function preProcess(file, t) {
108
+ try {
109
+ createScopeContext();
110
+ } catch (e) {
111
+ (0, _utilityHelpers.log)('error', '[::preProcess::]', e.message);
112
+ }
113
+ }
package/dist/plugin.js ADDED
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = _default;
7
+ var _constants = require("./utils/constants");
8
+ var _pre = _interopRequireDefault(require("./lifecycle/pre"));
9
+ var _post = _interopRequireDefault(require("./lifecycle/post"));
10
+ var _VariableDeclaration = _interopRequireDefault(require("./visitors/VariableDeclaration"));
11
+ var _AssignmentExpression = _interopRequireDefault(require("./visitors/AssignmentExpression"));
12
+ var _Identifier = _interopRequireDefault(require("./visitors/Identifier"));
13
+ var _Program = require("./visitors/Program");
14
+ var _FunctionDeclaration = require("./visitors/FunctionDeclaration");
15
+ var _utilityHelpers = require("./utils/utilityHelpers");
16
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
+ const virtualRegistry = {};
18
+ const prevVirtualRegistrySnap = {};
19
+ function _default({
20
+ types: t
21
+ }) {
22
+ const config = (0, _utilityHelpers.readCasperConfig)();
23
+ const seen = new WeakSet();
24
+ return {
25
+ name: _constants.PLUGIN_NAME,
26
+ pre(file) {
27
+ _pre.default.call(this, file, t);
28
+ },
29
+ visitor: {
30
+ Program: {
31
+ enter(path, state) {
32
+ _Program.programEnter.call(this, path, state, t, virtualRegistry, config);
33
+ },
34
+ exit(path, state) {
35
+ _Program.programExit.call(this, path, state, t);
36
+ }
37
+ },
38
+ VariableDeclarator(path, state) {
39
+ _VariableDeclaration.default.call(this, path, state, t, virtualRegistry);
40
+ },
41
+ AssignmentExpression(path, state) {
42
+ _AssignmentExpression.default.call(this, path, state, t, virtualRegistry);
43
+ },
44
+ Identifier(path, state) {
45
+ _Identifier.default.call(this, path, state, t, seen, virtualRegistry);
46
+ },
47
+ FunctionDeclaration: {
48
+ exit(path, state) {
49
+ _FunctionDeclaration.functionDeclarationExit.call(this, path, state, t, virtualRegistry);
50
+ }
51
+ }
52
+ },
53
+ post(file) {
54
+ _post.default.call(this, file, t, virtualRegistry, prevVirtualRegistrySnap);
55
+ }
56
+ };
57
+ }
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ "use strict";