unplugin-react-fine-grained-signals 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 +21 -0
- package/README.ja.md +250 -0
- package/README.md +261 -0
- package/dist/esbuild.d.ts +10 -0
- package/dist/esbuild.js +5 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/loader.d.ts +15 -0
- package/dist/loader.js +160 -0
- package/dist/rollup.d.ts +11 -0
- package/dist/rollup.js +5 -0
- package/dist/rspack.d.ts +9 -0
- package/dist/rspack.js +5 -0
- package/dist/unplugin-B2_q8KNi.js +1341 -0
- package/dist/unplugin-CG9_mdcA.d.ts +77 -0
- package/dist/vite.d.ts +11 -0
- package/dist/vite.js +5 -0
- package/dist/webpack.d.ts +9 -0
- package/dist/webpack.js +5 -0
- package/package.json +88 -0
package/dist/loader.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
//#region src/loader.ts
|
|
3
|
+
/**
|
|
4
|
+
* The webpack/rspack transform loader.
|
|
5
|
+
*
|
|
6
|
+
* unplugin ships its own loader for both compilers, and both copies of it hand
|
|
7
|
+
* the transform's source map on with
|
|
8
|
+
* `callback(null, res.code, map == null ? map : res.map || map)` -- so a plugin
|
|
9
|
+
* that runs with `enforce: "pre"`, and therefore sees no incoming map at all in
|
|
10
|
+
* a normal configuration, has its map discarded every single time. That matters
|
|
11
|
+
* here because Babel re-prints the whole file: every line number shifts, and a
|
|
12
|
+
* downstream loader then builds its map treating the already-transformed text
|
|
13
|
+
* as the original source, so breakpoints and stack traces land on lines that do
|
|
14
|
+
* not exist. Vite, Rollup and esbuild take the map straight off the `transform`
|
|
15
|
+
* hook's return value and are unaffected.
|
|
16
|
+
*
|
|
17
|
+
* This is that same loader with its map handling corrected, so
|
|
18
|
+
* `src/unplugin.ts` points the compiler's loader rule here instead:
|
|
19
|
+
*
|
|
20
|
+
* - with no incoming map -- the ordinary `enforce: "pre"` case -- the map the
|
|
21
|
+
* transform produced is passed on rather than dropped;
|
|
22
|
+
* - with an incoming map -- webpack lets several `pre` loaders chain, so
|
|
23
|
+
* `enforce: "pre"` does not actually guarantee this one runs first -- the two
|
|
24
|
+
* are composed, so neither the upstream loader's edits nor this transform's
|
|
25
|
+
* are lost from the positions a debugger ends up with.
|
|
26
|
+
*/
|
|
27
|
+
function toError(thrown) {
|
|
28
|
+
return thrown instanceof Error ? thrown : new Error(String(thrown));
|
|
29
|
+
}
|
|
30
|
+
/** webpack hands the incoming map on as an object or as its JSON text. */
|
|
31
|
+
function toSourceMapObject(map) {
|
|
32
|
+
if (typeof map === "string") try {
|
|
33
|
+
const parsed = JSON.parse(map);
|
|
34
|
+
return parsed !== null && typeof parsed === "object" ? parsed : null;
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return map !== null && typeof map === "object" ? map : null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A `sourceMappingURL` comment naming a map file rather than carrying one.
|
|
42
|
+
*
|
|
43
|
+
* Babel strips these itself, but only on the branch it takes when it found no
|
|
44
|
+
* input map -- so appending an input map below suppresses that stripping and
|
|
45
|
+
* would leave a stale `//# sourceMappingURL=App.tsx.map` line in the output.
|
|
46
|
+
* Rather than cut such a comment out of the source by hand (a text edit to the
|
|
47
|
+
* author's file, on a guess about what is comment and what is string), a file
|
|
48
|
+
* that carries one simply does not get an input map appended: it keeps exactly
|
|
49
|
+
* the behaviour it had before this loader forwarded incoming maps at all.
|
|
50
|
+
* Matching too eagerly therefore only costs composition for that one file,
|
|
51
|
+
* which is why this looks for the shape and not for a precise comment.
|
|
52
|
+
*/
|
|
53
|
+
const EXTERNAL_SOURCE_MAP_COMMENT = /(?:\/\/|\/\*)[@#][ \t]+sourceMappingURL=(?!data:)/;
|
|
54
|
+
/**
|
|
55
|
+
* The incoming map re-attached to `source` as a trailing inline
|
|
56
|
+
* `sourceMappingURL` comment, or `null` when there is no map worth attaching.
|
|
57
|
+
*
|
|
58
|
+
* Composing has to happen inside the Babel run that re-prints the file: Babel
|
|
59
|
+
* is the only thing that knows how its output positions relate to its input,
|
|
60
|
+
* and it already merges an input map into the map it emits. Its `inputSourceMap`
|
|
61
|
+
* option defaults to reading that map out of exactly this comment, and it lifts
|
|
62
|
+
* the comment out of the AST as it reads it, so nothing of it reaches the
|
|
63
|
+
* printed output -- which makes this the transform's `inputSourceMap` channel
|
|
64
|
+
* without the transform needing an option for it.
|
|
65
|
+
*
|
|
66
|
+
* Forwarding the incoming map must never make the result worse than not
|
|
67
|
+
* forwarding it, so several shapes are left behind rather than passed on: a map
|
|
68
|
+
* with no `sources` array makes Babel throw outright, and one whose `sources`
|
|
69
|
+
* is present but empty composes into a map with no sources at all, throwing
|
|
70
|
+
* away the perfectly good file name the transform's own map would have had.
|
|
71
|
+
*/
|
|
72
|
+
function inlineSourceMapComment(map, source) {
|
|
73
|
+
const candidate = toSourceMapObject(map);
|
|
74
|
+
if (candidate === null) return null;
|
|
75
|
+
if (Number(candidate.version) !== 3) return null;
|
|
76
|
+
if (typeof candidate.mappings !== "string") return null;
|
|
77
|
+
if (!Array.isArray(candidate.sources) || candidate.sources.length === 0) return null;
|
|
78
|
+
if (EXTERNAL_SOURCE_MAP_COMMENT.test(source)) return null;
|
|
79
|
+
let json;
|
|
80
|
+
try {
|
|
81
|
+
json = JSON.stringify(candidate);
|
|
82
|
+
} catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return `\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${Buffer.from(json, "utf8").toString("base64")}`;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Removes occurrences of the exact text appended above from a transform's
|
|
89
|
+
* result. Babel takes its own copy back out as it reads it, so this is for a
|
|
90
|
+
* `transform` hook that is not Babel and would print it straight back.
|
|
91
|
+
*
|
|
92
|
+
* The guarantee is only that: every byte-identical occurrence goes, whether or
|
|
93
|
+
* not this loader is what put it there. A file already containing a comment
|
|
94
|
+
* byte-identical to the one generated here -- which means already carrying this
|
|
95
|
+
* exact incoming map, inline -- would lose it, and is accepted as an edge case;
|
|
96
|
+
* on the Babel path it would not have survived anyway, since Babel filters out
|
|
97
|
+
* every inline map comment it sees rather than only the last. A comment naming
|
|
98
|
+
* a map *file* is a different matter and is handled before the fact, by
|
|
99
|
+
* `EXTERNAL_SOURCE_MAP_COMMENT` above.
|
|
100
|
+
*/
|
|
101
|
+
function withoutInlineSourceMap(code, comment) {
|
|
102
|
+
return comment === null ? code : code.replaceAll(comment, "");
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The `this` a `transform` hook is called with. This plugin's own transform is
|
|
106
|
+
* a pure `(code, id)` function that never touches it, so rather than rebuild
|
|
107
|
+
* unplugin's full build context out of compiler internals, this forwards the
|
|
108
|
+
* few context methods that have a direct loader equivalent and leaves it there.
|
|
109
|
+
*/
|
|
110
|
+
function createHookContext(loaderContext) {
|
|
111
|
+
return {
|
|
112
|
+
addWatchFile(file) {
|
|
113
|
+
loaderContext.addDependency?.(file);
|
|
114
|
+
},
|
|
115
|
+
getWatchFiles() {
|
|
116
|
+
return loaderContext.getDependencies?.() ?? [];
|
|
117
|
+
},
|
|
118
|
+
error(message) {
|
|
119
|
+
throw toError(message);
|
|
120
|
+
},
|
|
121
|
+
warn(message) {
|
|
122
|
+
const warning = toError(message);
|
|
123
|
+
if (loaderContext.emitWarning !== void 0) loaderContext.emitWarning(warning);
|
|
124
|
+
else console.warn(warning.message);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function reactFineGrainedSignalsLoader(source, map) {
|
|
129
|
+
const callback = this.async();
|
|
130
|
+
const query = this.query;
|
|
131
|
+
const plugin = query !== null && typeof query === "object" ? query.plugin ?? void 0 : void 0;
|
|
132
|
+
const hook = plugin?.transform;
|
|
133
|
+
const handler = typeof hook === "function" ? hook : hook?.handler;
|
|
134
|
+
if (handler === void 0) {
|
|
135
|
+
callback(null, source, map);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const id = this.resource;
|
|
139
|
+
if (plugin?.transformInclude !== void 0 && plugin.transformInclude(id) !== true) {
|
|
140
|
+
callback(null, source, map);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const runTransform = (input) => {
|
|
144
|
+
try {
|
|
145
|
+
return Promise.resolve(handler.call(createHookContext(this), input, id));
|
|
146
|
+
} catch (thrown) {
|
|
147
|
+
return Promise.reject(toError(thrown));
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
const inlineMap = inlineSourceMapComment(map, source);
|
|
151
|
+
(inlineMap === null ? runTransform(source) : runTransform(source + inlineMap).catch(() => runTransform(source))).then((result) => {
|
|
152
|
+
if (result === null || result === void 0) callback(null, source, map);
|
|
153
|
+
else if (typeof result === "string") callback(null, withoutInlineSourceMap(result, inlineMap), map);
|
|
154
|
+
else callback(null, withoutInlineSourceMap(result.code, inlineMap), result.map ?? map);
|
|
155
|
+
}, (thrown) => {
|
|
156
|
+
callback(toError(thrown));
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
//#endregion
|
|
160
|
+
export { reactFineGrainedSignalsLoader as default };
|
package/dist/rollup.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { a as createBundlerPlugin, c as resolveEsbuildLoader, d as ReactFineGrainedSignalsTransform, i as canTransform, l as ReactFineGrainedSignalsMode, n as EsbuildLoaderName, o as pluginName, r as ReactFineGrainedSignalsOptions, s as reactFineGrainedSignals, t as BundlerTransformOutput, u as ReactFineGrainedSignalsReactCompiler } from "./unplugin-CG9_mdcA.js";
|
|
2
|
+
//#region src/rollup.d.ts
|
|
3
|
+
/** A minimal Rollup-compatible plugin shape. */
|
|
4
|
+
interface RollupPlugin {
|
|
5
|
+
name: string;
|
|
6
|
+
enforce?: "pre" | "post";
|
|
7
|
+
transform?: (code: string, id: string) => BundlerTransformOutput;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: (options?: ReactFineGrainedSignalsOptions) => RollupPlugin;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { BundlerTransformOutput, EsbuildLoaderName, type ReactFineGrainedSignalsMode, ReactFineGrainedSignalsOptions, type ReactFineGrainedSignalsReactCompiler, type ReactFineGrainedSignalsTransform, RollupPlugin, canTransform, createBundlerPlugin, _default as default, pluginName, reactFineGrainedSignals, resolveEsbuildLoader };
|
package/dist/rollup.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { a as resolveEsbuildLoader, i as reactFineGrainedSignals, n as createBundlerPlugin, r as pluginName, t as canTransform } from "./unplugin-B2_q8KNi.js";
|
|
2
|
+
//#region src/rollup.ts
|
|
3
|
+
var rollup_default = createBundlerPlugin("rollup");
|
|
4
|
+
//#endregion
|
|
5
|
+
export { canTransform, createBundlerPlugin, rollup_default as default, pluginName, reactFineGrainedSignals, resolveEsbuildLoader };
|
package/dist/rspack.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { a as createBundlerPlugin, c as resolveEsbuildLoader, d as ReactFineGrainedSignalsTransform, i as canTransform, l as ReactFineGrainedSignalsMode, n as EsbuildLoaderName, o as pluginName, r as ReactFineGrainedSignalsOptions, s as reactFineGrainedSignals, t as BundlerTransformOutput, u as ReactFineGrainedSignalsReactCompiler } from "./unplugin-CG9_mdcA.js";
|
|
2
|
+
//#region src/rspack.d.ts
|
|
3
|
+
/** The compiler-plugin contract used by Rspack. */
|
|
4
|
+
interface RspackPlugin {
|
|
5
|
+
apply(compiler: unknown): void;
|
|
6
|
+
}
|
|
7
|
+
declare const _default: (options?: ReactFineGrainedSignalsOptions) => RspackPlugin;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { BundlerTransformOutput, EsbuildLoaderName, type ReactFineGrainedSignalsMode, ReactFineGrainedSignalsOptions, type ReactFineGrainedSignalsReactCompiler, type ReactFineGrainedSignalsTransform, RspackPlugin, canTransform, createBundlerPlugin, _default as default, pluginName, reactFineGrainedSignals, resolveEsbuildLoader };
|
package/dist/rspack.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { a as resolveEsbuildLoader, i as reactFineGrainedSignals, n as createBundlerPlugin, r as pluginName, t as canTransform } from "./unplugin-B2_q8KNi.js";
|
|
2
|
+
//#region src/rspack.ts
|
|
3
|
+
var rspack_default = createBundlerPlugin("rspack");
|
|
4
|
+
//#endregion
|
|
5
|
+
export { canTransform, createBundlerPlugin, rspack_default as default, pluginName, reactFineGrainedSignals, resolveEsbuildLoader };
|