@ecrindigital/facetpack 0.1.1
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 +21 -0
- package/README.md +141 -0
- package/dist/cache.d.ts +8 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/index.cjs +330 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +302 -0
- package/dist/resolver.d.ts +6 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/transformer.cjs +214 -0
- package/dist/transformer.d.ts +7 -0
- package/dist/transformer.d.ts.map +1 -0
- package/dist/transformer.js +211 -0
- package/dist/types.d.ts +59 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/withFacetpack.d.ts +4 -0
- package/dist/withFacetpack.d.ts.map +1 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-present Ecrin Digital
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# facetpack
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/facetpack)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
> High-performance Metro transformer powered by [OXC](https://oxc.rs) and Rust.
|
|
7
|
+
|
|
8
|
+
Replace Babel with a blazing-fast native transformer in your React Native project.
|
|
9
|
+
|
|
10
|
+
Built by [Ecrin Digital](https://ecrin.digital).
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **10-50x Faster** - Native Rust transformer powered by OXC
|
|
15
|
+
- **Drop-in Replacement** - Just wrap your Metro config
|
|
16
|
+
- **TypeScript Support** - Full TypeScript parsing and type stripping
|
|
17
|
+
- **JSX/TSX Support** - Automatic and classic runtime support
|
|
18
|
+
- **Source Maps** - Full source map support for debugging
|
|
19
|
+
- **Zero Config** - Works out of the box with sensible defaults
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install facetpack facetpack-native
|
|
25
|
+
# or
|
|
26
|
+
yarn add facetpack facetpack-native
|
|
27
|
+
# or
|
|
28
|
+
pnpm add facetpack facetpack-native
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
Wrap your Metro configuration with `withFacetpack`:
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
// metro.config.js
|
|
37
|
+
const { getDefaultConfig } = require('@react-native/metro-config');
|
|
38
|
+
const { withFacetpack } = require('facetpack');
|
|
39
|
+
|
|
40
|
+
const config = getDefaultConfig(__dirname);
|
|
41
|
+
|
|
42
|
+
module.exports = withFacetpack(config);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### With Options
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
// metro.config.js
|
|
49
|
+
const { getDefaultConfig } = require('@react-native/metro-config');
|
|
50
|
+
const { withFacetpack } = require('facetpack');
|
|
51
|
+
|
|
52
|
+
const config = getDefaultConfig(__dirname);
|
|
53
|
+
|
|
54
|
+
module.exports = withFacetpack(config, {
|
|
55
|
+
// JSX runtime: 'automatic' (default) or 'classic'
|
|
56
|
+
jsxRuntime: 'automatic',
|
|
57
|
+
|
|
58
|
+
// Import source for automatic runtime
|
|
59
|
+
jsxImportSource: 'react',
|
|
60
|
+
|
|
61
|
+
// Enable TypeScript transformation (default: true)
|
|
62
|
+
typescript: true,
|
|
63
|
+
|
|
64
|
+
// Enable JSX transformation (default: true)
|
|
65
|
+
jsx: true,
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### With Expo
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
// metro.config.js
|
|
73
|
+
const { getDefaultConfig } = require('expo/metro-config');
|
|
74
|
+
const { withFacetpack } = require('facetpack');
|
|
75
|
+
|
|
76
|
+
const config = getDefaultConfig(__dirname);
|
|
77
|
+
|
|
78
|
+
module.exports = withFacetpack(config);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## API
|
|
82
|
+
|
|
83
|
+
### `withFacetpack(config, options?)`
|
|
84
|
+
|
|
85
|
+
Wraps a Metro configuration with the Facetpack transformer.
|
|
86
|
+
|
|
87
|
+
#### Parameters
|
|
88
|
+
|
|
89
|
+
| Parameter | Type | Description |
|
|
90
|
+
|-----------|------|-------------|
|
|
91
|
+
| `config` | `MetroConfig` | Your Metro configuration object |
|
|
92
|
+
| `options` | `FacetpackOptions` | Optional configuration options |
|
|
93
|
+
|
|
94
|
+
#### Options
|
|
95
|
+
|
|
96
|
+
| Option | Type | Default | Description |
|
|
97
|
+
|--------|------|---------|-------------|
|
|
98
|
+
| `jsx` | `boolean` | `true` | Enable JSX transformation |
|
|
99
|
+
| `jsxRuntime` | `'automatic' \| 'classic'` | `'automatic'` | JSX runtime mode |
|
|
100
|
+
| `jsxImportSource` | `string` | `'react'` | Import source for automatic runtime |
|
|
101
|
+
| `jsxPragma` | `string` | `'React.createElement'` | Pragma for classic runtime |
|
|
102
|
+
| `jsxPragmaFrag` | `string` | `'React.Fragment'` | Fragment pragma for classic runtime |
|
|
103
|
+
| `typescript` | `boolean` | `true` | Strip TypeScript types |
|
|
104
|
+
| `sourceExts` | `string[]` | `['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs']` | File extensions to transform |
|
|
105
|
+
|
|
106
|
+
## How It Works
|
|
107
|
+
|
|
108
|
+
Facetpack replaces Metro's default Babel transformer with a native Rust transformer powered by [OXC](https://oxc.rs). This provides significant performance improvements:
|
|
109
|
+
|
|
110
|
+
| Operation | vs Babel |
|
|
111
|
+
|-----------|----------|
|
|
112
|
+
| Parse | ~50x faster |
|
|
113
|
+
| Transform | ~20x faster |
|
|
114
|
+
|
|
115
|
+
The transformer handles:
|
|
116
|
+
- TypeScript → JavaScript (type stripping)
|
|
117
|
+
- JSX → JavaScript (createElement or jsx-runtime)
|
|
118
|
+
- Source map generation
|
|
119
|
+
|
|
120
|
+
## Requirements
|
|
121
|
+
|
|
122
|
+
- React Native 0.73+
|
|
123
|
+
- Metro 0.80+
|
|
124
|
+
- Node.js 18+
|
|
125
|
+
|
|
126
|
+
## Compatibility
|
|
127
|
+
|
|
128
|
+
Facetpack is designed to be a drop-in replacement for Babel in most React Native projects. However, if you rely on specific Babel plugins or transforms, you may need to keep Babel for those files.
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
MIT - see [LICENSE](./LICENSE) for details.
|
|
133
|
+
|
|
134
|
+
## Credits
|
|
135
|
+
|
|
136
|
+
- [OXC](https://oxc.rs) - The high-performance JavaScript toolchain
|
|
137
|
+
- [NAPI-RS](https://napi.rs) - Rust bindings for Node.js
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
Made with Rust by [Ecrin Digital](https://ecrin.digital)
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function setCachedResolutions(originModulePath: string, resolutions: Map<string, string | null>): void;
|
|
2
|
+
export declare function getCachedResolution(originModulePath: string, specifier: string): string | null | undefined;
|
|
3
|
+
export declare function clearCache(): void;
|
|
4
|
+
export declare function getCacheStats(): {
|
|
5
|
+
files: number;
|
|
6
|
+
resolutions: number;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AASA,wBAAgB,oBAAoB,CAClC,gBAAgB,EAAE,MAAM,EACxB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,GACtC,IAAI,CASN;AAED,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,GAAG,SAAS,CAa3B;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED,wBAAgB,aAAa,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAMtE"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
|
+
var __toCommonJS = (from) => {
|
|
7
|
+
var entry = __moduleCache.get(from), desc;
|
|
8
|
+
if (entry)
|
|
9
|
+
return entry;
|
|
10
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
13
|
+
get: () => from[key],
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
}));
|
|
16
|
+
__moduleCache.set(from, entry);
|
|
17
|
+
return entry;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/index.ts
|
|
30
|
+
var exports_src = {};
|
|
31
|
+
__export(exports_src, {
|
|
32
|
+
withFacetpack: () => withFacetpack,
|
|
33
|
+
transform: () => transform,
|
|
34
|
+
setTransformerOptions: () => setTransformerOptions,
|
|
35
|
+
resolveSync: () => import_facetpack_native3.resolveSync,
|
|
36
|
+
getStoredOptions: () => getStoredOptions,
|
|
37
|
+
getCacheStats: () => getCacheStats,
|
|
38
|
+
createTransformer: () => createTransformer,
|
|
39
|
+
createResolver: () => createResolver,
|
|
40
|
+
clearCache: () => clearCache
|
|
41
|
+
});
|
|
42
|
+
module.exports = __toCommonJS(exports_src);
|
|
43
|
+
|
|
44
|
+
// src/withFacetpack.ts
|
|
45
|
+
var import_facetpack_native = require("@ecrindigital/facetpack-native");
|
|
46
|
+
|
|
47
|
+
// src/cache.ts
|
|
48
|
+
var resolutionCache = new Map;
|
|
49
|
+
var CACHE_TTL = 30000;
|
|
50
|
+
function setCachedResolutions(originModulePath, resolutions) {
|
|
51
|
+
const now = Date.now();
|
|
52
|
+
const cached = new Map;
|
|
53
|
+
for (const [specifier, path] of resolutions) {
|
|
54
|
+
cached.set(specifier, { path, timestamp: now });
|
|
55
|
+
}
|
|
56
|
+
resolutionCache.set(originModulePath, cached);
|
|
57
|
+
}
|
|
58
|
+
function getCachedResolution(originModulePath, specifier) {
|
|
59
|
+
const fileCache = resolutionCache.get(originModulePath);
|
|
60
|
+
if (!fileCache)
|
|
61
|
+
return;
|
|
62
|
+
const cached = fileCache.get(specifier);
|
|
63
|
+
if (!cached)
|
|
64
|
+
return;
|
|
65
|
+
if (Date.now() - cached.timestamp > CACHE_TTL) {
|
|
66
|
+
fileCache.delete(specifier);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
return cached.path;
|
|
70
|
+
}
|
|
71
|
+
function clearCache() {
|
|
72
|
+
resolutionCache.clear();
|
|
73
|
+
}
|
|
74
|
+
function getCacheStats() {
|
|
75
|
+
let resolutions = 0;
|
|
76
|
+
for (const fileCache of resolutionCache.values()) {
|
|
77
|
+
resolutions += fileCache.size;
|
|
78
|
+
}
|
|
79
|
+
return { files: resolutionCache.size, resolutions };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/withFacetpack.ts
|
|
83
|
+
var import_path = require("path");
|
|
84
|
+
var import_url = require("url");
|
|
85
|
+
var DEFAULT_SOURCE_EXTS = ["ts", "tsx", "js", "jsx", "mjs", "cjs"];
|
|
86
|
+
var __filename2 = import_url.fileURLToPath("file:///Users/alexischangridel/Projects/ecrindigital/facetpack/packages/facetpack/src/withFacetpack.ts");
|
|
87
|
+
var __dirname2 = import_path.dirname(__filename2);
|
|
88
|
+
function withFacetpack(config, options = {}) {
|
|
89
|
+
const sourceExts = options.sourceExts ?? DEFAULT_SOURCE_EXTS;
|
|
90
|
+
const transformerPath = import_path.join(__dirname2, "transformer.js");
|
|
91
|
+
storeTransformerOptions(options);
|
|
92
|
+
return {
|
|
93
|
+
...config,
|
|
94
|
+
transformer: {
|
|
95
|
+
...config.transformer,
|
|
96
|
+
babelTransformerPath: transformerPath,
|
|
97
|
+
getTransformOptions: async (entryPoints, opts, getDepsOf) => {
|
|
98
|
+
const baseOptions = await config.transformer?.getTransformOptions?.(entryPoints, opts, getDepsOf);
|
|
99
|
+
return {
|
|
100
|
+
...baseOptions,
|
|
101
|
+
transform: {
|
|
102
|
+
...baseOptions?.transform,
|
|
103
|
+
experimentalImportSupport: true,
|
|
104
|
+
inlineRequires: true
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
resolver: {
|
|
110
|
+
...config.resolver,
|
|
111
|
+
sourceExts: [
|
|
112
|
+
...new Set([
|
|
113
|
+
...config.resolver?.sourceExts ?? [],
|
|
114
|
+
...sourceExts
|
|
115
|
+
])
|
|
116
|
+
],
|
|
117
|
+
resolveRequest: (context, moduleName, platform) => {
|
|
118
|
+
if (context.originModulePath.includes("node_modules")) {
|
|
119
|
+
return context.resolveRequest(context, moduleName, platform);
|
|
120
|
+
}
|
|
121
|
+
const cached = getCachedResolution(context.originModulePath, moduleName);
|
|
122
|
+
if (cached !== undefined) {
|
|
123
|
+
if (cached) {
|
|
124
|
+
return { type: "sourceFile", filePath: cached };
|
|
125
|
+
}
|
|
126
|
+
return context.resolveRequest(context, moduleName, platform);
|
|
127
|
+
}
|
|
128
|
+
const directory = context.originModulePath.substring(0, context.originModulePath.lastIndexOf("/"));
|
|
129
|
+
const result = import_facetpack_native.resolveSync(directory, moduleName, {
|
|
130
|
+
extensions: [...sourceExts.map((ext) => `.${ext}`), ".json"],
|
|
131
|
+
mainFields: ["react-native", "browser", "main"],
|
|
132
|
+
conditionNames: ["react-native", "import", "require"]
|
|
133
|
+
});
|
|
134
|
+
if (result.path) {
|
|
135
|
+
return { type: "sourceFile", filePath: result.path };
|
|
136
|
+
}
|
|
137
|
+
return context.resolveRequest(context, moduleName, platform);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function storeTransformerOptions(options) {
|
|
143
|
+
process.env.FACETPACK_OPTIONS = JSON.stringify(options);
|
|
144
|
+
}
|
|
145
|
+
function getStoredOptions() {
|
|
146
|
+
try {
|
|
147
|
+
const optionsJson = process.env.FACETPACK_OPTIONS;
|
|
148
|
+
if (optionsJson) {
|
|
149
|
+
return JSON.parse(optionsJson);
|
|
150
|
+
}
|
|
151
|
+
} catch {}
|
|
152
|
+
return {};
|
|
153
|
+
}
|
|
154
|
+
// src/transformer.ts
|
|
155
|
+
var import_facetpack_native2 = require("@ecrindigital/facetpack-native");
|
|
156
|
+
var import_parser = require("@babel/parser");
|
|
157
|
+
var IMPORT_REGEX = /(?:import|export)\s+(?:[\s\S]*?\s+from\s+)?['"]([^'"]+)['"]/g;
|
|
158
|
+
var REQUIRE_REGEX = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
159
|
+
function extractSpecifiers(code) {
|
|
160
|
+
const specifiers = new Set;
|
|
161
|
+
let match;
|
|
162
|
+
while ((match = IMPORT_REGEX.exec(code)) !== null) {
|
|
163
|
+
if (match[1])
|
|
164
|
+
specifiers.add(match[1]);
|
|
165
|
+
}
|
|
166
|
+
while ((match = REQUIRE_REGEX.exec(code)) !== null) {
|
|
167
|
+
if (match[1])
|
|
168
|
+
specifiers.add(match[1]);
|
|
169
|
+
}
|
|
170
|
+
return Array.from(specifiers);
|
|
171
|
+
}
|
|
172
|
+
function preResolveImports(filename, code, sourceExts) {
|
|
173
|
+
const specifiers = extractSpecifiers(code);
|
|
174
|
+
if (specifiers.length === 0)
|
|
175
|
+
return;
|
|
176
|
+
const directory = filename.substring(0, filename.lastIndexOf("/"));
|
|
177
|
+
const results = import_facetpack_native2.resolveBatchSync(directory, specifiers, {
|
|
178
|
+
extensions: [...sourceExts.map((ext) => `.${ext}`), ".json"],
|
|
179
|
+
mainFields: ["react-native", "browser", "main"],
|
|
180
|
+
conditionNames: ["react-native", "import", "require"]
|
|
181
|
+
});
|
|
182
|
+
const resolutions = new Map;
|
|
183
|
+
for (let i = 0;i < specifiers.length; i++) {
|
|
184
|
+
const specifier = specifiers[i];
|
|
185
|
+
if (specifier) {
|
|
186
|
+
resolutions.set(specifier, results[i]?.path ?? null);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
setCachedResolutions(filename, resolutions);
|
|
190
|
+
}
|
|
191
|
+
var defaultOptions = {
|
|
192
|
+
jsx: true,
|
|
193
|
+
jsxRuntime: "automatic",
|
|
194
|
+
jsxImportSource: "react",
|
|
195
|
+
jsxPragma: "React.createElement",
|
|
196
|
+
jsxPragmaFrag: "React.Fragment",
|
|
197
|
+
typescript: true,
|
|
198
|
+
sourceExts: ["ts", "tsx", "js", "jsx", "mjs", "cjs"]
|
|
199
|
+
};
|
|
200
|
+
var globalOptions = {};
|
|
201
|
+
var fallbackTransformer = null;
|
|
202
|
+
function getFallbackTransformer() {
|
|
203
|
+
if (fallbackTransformer) {
|
|
204
|
+
return fallbackTransformer;
|
|
205
|
+
}
|
|
206
|
+
const transformerPaths = [
|
|
207
|
+
"@expo/metro-config/babel-transformer",
|
|
208
|
+
"@react-native/metro-babel-transformer",
|
|
209
|
+
"metro-react-native-babel-transformer"
|
|
210
|
+
];
|
|
211
|
+
for (const transformerPath of transformerPaths) {
|
|
212
|
+
try {
|
|
213
|
+
fallbackTransformer = require(transformerPath);
|
|
214
|
+
return fallbackTransformer;
|
|
215
|
+
} catch {}
|
|
216
|
+
}
|
|
217
|
+
fallbackTransformer = {
|
|
218
|
+
transform: ({ src }) => ({ code: src, map: null })
|
|
219
|
+
};
|
|
220
|
+
return fallbackTransformer;
|
|
221
|
+
}
|
|
222
|
+
function setTransformerOptions(options) {
|
|
223
|
+
globalOptions = options;
|
|
224
|
+
}
|
|
225
|
+
function getOptions() {
|
|
226
|
+
return { ...defaultOptions, ...globalOptions };
|
|
227
|
+
}
|
|
228
|
+
function isNodeModules(filename) {
|
|
229
|
+
return filename.includes("node_modules");
|
|
230
|
+
}
|
|
231
|
+
function shouldTransform(filename, options) {
|
|
232
|
+
if (isNodeModules(filename)) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
const ext = filename.split(".").pop()?.toLowerCase();
|
|
236
|
+
if (!ext)
|
|
237
|
+
return false;
|
|
238
|
+
return options.sourceExts.includes(ext);
|
|
239
|
+
}
|
|
240
|
+
function transform(params) {
|
|
241
|
+
const { filename, src, options: metroOptions } = params;
|
|
242
|
+
const opts = getOptions();
|
|
243
|
+
if (process.env.FACETPACK_DEBUG) {
|
|
244
|
+
console.log(`[Facetpack] Processing: ${filename}`);
|
|
245
|
+
}
|
|
246
|
+
if (!shouldTransform(filename, opts)) {
|
|
247
|
+
if (process.env.FACETPACK_DEBUG) {
|
|
248
|
+
console.log(`[Facetpack] Fallback: ${filename}`);
|
|
249
|
+
}
|
|
250
|
+
return getFallbackTransformer().transform(params);
|
|
251
|
+
}
|
|
252
|
+
if (process.env.FACETPACK_DEBUG) {
|
|
253
|
+
console.log(`[Facetpack] OXC Transform: ${filename}`);
|
|
254
|
+
}
|
|
255
|
+
try {
|
|
256
|
+
const isClassic = opts.jsxRuntime === "classic";
|
|
257
|
+
const result = import_facetpack_native2.transformSync(filename, src, {
|
|
258
|
+
jsx: opts.jsx,
|
|
259
|
+
jsxRuntime: isClassic ? import_facetpack_native2.JsxRuntime.Classic : import_facetpack_native2.JsxRuntime.Automatic,
|
|
260
|
+
...isClassic ? { jsxPragma: opts.jsxPragma, jsxPragmaFrag: opts.jsxPragmaFrag } : { jsxImportSource: opts.jsxImportSource },
|
|
261
|
+
typescript: opts.typescript,
|
|
262
|
+
sourcemap: metroOptions.dev
|
|
263
|
+
});
|
|
264
|
+
if (result.errors.length > 0) {
|
|
265
|
+
const errorMessage = result.errors.join(`
|
|
266
|
+
`);
|
|
267
|
+
throw new Error(`Facetpack transform error in ${filename}:
|
|
268
|
+
${errorMessage}`);
|
|
269
|
+
}
|
|
270
|
+
preResolveImports(filename, result.code, opts.sourceExts);
|
|
271
|
+
const ast = import_parser.parse(result.code, {
|
|
272
|
+
sourceType: "unambiguous",
|
|
273
|
+
plugins: ["jsx"]
|
|
274
|
+
});
|
|
275
|
+
const output = {
|
|
276
|
+
ast,
|
|
277
|
+
code: result.code,
|
|
278
|
+
map: result.map ? JSON.parse(result.map) : null
|
|
279
|
+
};
|
|
280
|
+
if (process.env.FACETPACK_DEBUG) {
|
|
281
|
+
console.log(`[Facetpack] Output for ${filename}:`);
|
|
282
|
+
console.log(result.code.slice(0, 500));
|
|
283
|
+
}
|
|
284
|
+
return output;
|
|
285
|
+
} catch (error) {
|
|
286
|
+
if (error instanceof Error) {
|
|
287
|
+
error.message = `[Facetpack] ${error.message}`;
|
|
288
|
+
}
|
|
289
|
+
throw error;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function createTransformer(options = {}) {
|
|
293
|
+
const opts = { ...defaultOptions, ...options };
|
|
294
|
+
return {
|
|
295
|
+
transform(params) {
|
|
296
|
+
const { filename, src, options: metroOptions } = params;
|
|
297
|
+
if (!shouldTransform(filename, opts)) {
|
|
298
|
+
return getFallbackTransformer().transform(params);
|
|
299
|
+
}
|
|
300
|
+
const isClassic = opts.jsxRuntime === "classic";
|
|
301
|
+
const result = import_facetpack_native2.transformSync(filename, src, {
|
|
302
|
+
jsx: opts.jsx,
|
|
303
|
+
jsxRuntime: isClassic ? import_facetpack_native2.JsxRuntime.Classic : import_facetpack_native2.JsxRuntime.Automatic,
|
|
304
|
+
...isClassic ? { jsxPragma: opts.jsxPragma, jsxPragmaFrag: opts.jsxPragmaFrag } : { jsxImportSource: opts.jsxImportSource },
|
|
305
|
+
typescript: opts.typescript,
|
|
306
|
+
sourcemap: metroOptions.dev
|
|
307
|
+
});
|
|
308
|
+
if (result.errors.length > 0) {
|
|
309
|
+
throw new Error(`Facetpack transform error in ${filename}:
|
|
310
|
+
${result.errors.join(`
|
|
311
|
+
`)}`);
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
code: result.code,
|
|
315
|
+
map: result.map ? JSON.parse(result.map) : null
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
// src/resolver.ts
|
|
321
|
+
var import_facetpack_native3 = require("@ecrindigital/facetpack-native");
|
|
322
|
+
function createResolver(options) {
|
|
323
|
+
return {
|
|
324
|
+
resolve(originModulePath, moduleName) {
|
|
325
|
+
const directory = originModulePath.substring(0, originModulePath.lastIndexOf("/"));
|
|
326
|
+
const result = import_facetpack_native3.resolveSync(directory, moduleName, options);
|
|
327
|
+
return result.path ?? null;
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { withFacetpack, getStoredOptions } from './withFacetpack';
|
|
2
|
+
export { transform, createTransformer, setTransformerOptions } from './transformer';
|
|
3
|
+
export { createResolver, resolveSync } from './resolver';
|
|
4
|
+
export { clearCache, getCacheStats } from './cache';
|
|
5
|
+
export type { FacetpackOptions, MetroConfig, TransformParams, TransformOptions, TransformResult, } from './types';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AACnF,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACnD,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,SAAS,CAAA"}
|