noxcturnal 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/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # Noxcturnal
2
+
3
+ Noxcturnal is a native-backed JavaScript transformation library. It combines a typed,
4
+ Babel-like visitor API in TypeScript with parsing, semantic analysis, traversal, edit validation,
5
+ rendering, and source-map generation in Rust.
6
+
7
+ Noxcturnal is an independent transform runtime. It is not a Metro transformer and does not collect
8
+ dependencies, rewrite modules, or wrap output for a particular framework.
9
+
10
+ > [!NOTE]
11
+ > Noxcturnal is under active development. Its public API may change before the first stable release.
12
+
13
+ ## Installation
14
+
15
+ ```sh
16
+ pnpm add noxcturnal
17
+ ```
18
+
19
+ Noxcturnal requires Node.js 18 or later. The package selects a prebuilt native binary for supported
20
+ macOS, Linux, and Windows targets.
21
+
22
+ ## Usage
23
+
24
+ Plugins declare exactly which nodes and fields they need. Noxcturnal compiles those declarations
25
+ into native routes, sends only the requested data to JavaScript, and commits the resulting edits as
26
+ one transaction.
27
+
28
+ ```ts
29
+ import { defineNativePipeline, defineNativePlugin, defineVisitor, transform } from 'noxcturnal';
30
+
31
+ const replaceBuildId = defineNativePlugin({
32
+ name: 'replace-build-id',
33
+ contract: { metadata: { writes: ['replacedBuildId'] } },
34
+ visitors: [
35
+ defineVisitor(
36
+ 'Identifier',
37
+ {
38
+ fields: ['name', 'global'],
39
+ where: { name: { equals: '__BUILD_ID__' } },
40
+ },
41
+ path => {
42
+ if (path.node.global) {
43
+ path.replaceWith(path.context.code.stringLiteral('development'));
44
+ path.context.metadata.set('replacedBuildId', true);
45
+ }
46
+ },
47
+ ),
48
+ ],
49
+ });
50
+
51
+ const pipeline = defineNativePipeline({
52
+ phases: [{ name: 'application', plugins: [replaceBuildId] }],
53
+ });
54
+
55
+ const result = transform('console.log(__BUILD_ID__);', 'app.js', pipeline);
56
+
57
+ if (result.status === 'complete') {
58
+ console.log(result.code);
59
+ }
60
+ ```
61
+
62
+ Every plugin in a phase observes the same immutable input. Its edits become visible together at the
63
+ phase boundary, after validation and an optional reparse. Split dependent transforms into separate
64
+ phases when a later transform must observe an earlier transform's output.
65
+
66
+ ### Configuration and per-file data
67
+
68
+ Pipeline definitions describe reusable program configuration:
69
+
70
+ - `plugin.withOptions(options)` creates a definition with different declared behavior.
71
+ - `plugin.withParameters(values)` binds values used by native predicates.
72
+ - `pluginData` passes current-file data to state factories, hooks, and visitors.
73
+
74
+ ```ts
75
+ const result = transform(source, filename, pipeline, {
76
+ pluginData: { platform: 'ios' },
77
+ });
78
+ ```
79
+
80
+ Do not close over per-file data in a reusable plugin definition. Read it from `pluginData` instead.
81
+ If that data affects output, include it in the consumer's transform-result cache key;
82
+ `pipelineCacheKey` intentionally covers only Noxcturnal-owned configuration.
83
+
84
+ ### Native transforms
85
+
86
+ A phase can run declarative native transforms without a JavaScript visitor:
87
+
88
+ ```ts
89
+ const pipeline = defineNativePipeline({
90
+ phases: [
91
+ {
92
+ name: 'syntax',
93
+ native: {
94
+ typescript: 'strip',
95
+ transforms: {
96
+ optionalChaining: { loose: false },
97
+ nullishCoalescingOperator: { loose: false },
98
+ },
99
+ },
100
+ },
101
+ ],
102
+ });
103
+ ```
104
+
105
+ The native surface includes TypeScript and Flow erasure, JSX modes, React Compiler and React
106
+ Refresh integration, common ES syntax lowering, constant folding, and dead-code elimination.
107
+
108
+ ### Transform outcomes
109
+
110
+ `transform` has three outcomes:
111
+
112
+ - A successful transform returns a `NativeTransformResult`.
113
+ - An intentional compatibility boundary returns a `NativeBailoutResult` with the pristine input in
114
+ `source`.
115
+ - Invalid input or configuration and internal failures throw.
116
+
117
+ Run a compatibility transformer only for a returned bailout. Thrown failures should propagate.
118
+ Syntax failures use `TransformSyntaxError`; fatal native failures use `NativeTransformError` with
119
+ the stable code `NOXCTURNAL_TRANSFORM_ERROR`.
120
+
121
+ ## Development
122
+
123
+ The reproducible development environment includes Node.js, pnpm, Rust, CMake, Ninja, Python, and
124
+ the C++ tools needed to build the optional Hermes-backed Flow parser.
125
+
126
+ ```sh
127
+ nix develop
128
+ pnpm install
129
+ pnpm build
130
+ pnpm check
131
+ pnpm benchmark
132
+ ```
133
+
134
+ Use `pnpm format` to format the TypeScript and Rust sources. User-visible changes should include a
135
+ changeset because the main package and its native platform packages are released as one fixed
136
+ version group.
137
+
138
+ The test suite is organized by ownership and purpose; see [test/README.md](test/README.md) before
139
+ adding, moving, or deleting coverage.
140
+
141
+ ## License
142
+
143
+ MIT