@rsvelte/vite-plugin-svelte-native 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.md +23 -0
- package/envelope.js +335 -0
- package/index.cjs +134 -0
- package/index.d.ts +377 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yuichiro Yamashita
|
|
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,23 @@
|
|
|
1
|
+
# @rsvelte/vite-plugin-svelte
|
|
2
|
+
|
|
3
|
+
Workspace package and changesets version anchor for the Vite plugin that delegates to the rsvelte compiler.
|
|
4
|
+
|
|
5
|
+
## Status
|
|
6
|
+
|
|
7
|
+
`private: true` until distribution is decided. The Rust side already exposes the napi bindings the plugin will use (`compile`, `preprocess`, `hmrDiff`, `resolveId` in `src/napi.rs`; helpers in `src/vps/`).
|
|
8
|
+
|
|
9
|
+
The plan in `docs/ecosystem-implementation-plan.md` (Wave 3) splits this into two npm packages:
|
|
10
|
+
|
|
11
|
+
- `@rsvelte/vite-plugin-svelte` (this directory) — the JS-side Vite plugin façade. Maintains the same public API as `@sveltejs/vite-plugin-svelte`, loads the native module, and translates Vite hooks into NAPI calls.
|
|
12
|
+
- `@rsvelte/vite-plugin-svelte-native` — the napi-rs prebuilt-binary package set (one per platform triple), produced by a matrix build.
|
|
13
|
+
|
|
14
|
+
To go live:
|
|
15
|
+
|
|
16
|
+
1. Add the napi-rs platform matrix build to CI (target the rsvelte crate with `--features napi`).
|
|
17
|
+
2. Create the `@rsvelte/vite-plugin-svelte-native` workspace package and its per-triple siblings.
|
|
18
|
+
3. Add the JS entrypoint here that imports from `@rsvelte/vite-plugin-svelte-native`.
|
|
19
|
+
4. Flip `private` to `false` on both packages.
|
|
20
|
+
|
|
21
|
+
## Release flow
|
|
22
|
+
|
|
23
|
+
Versioning is handled by the same changesets pipeline as `@rsvelte/compiler`. See `.github/workflows/release.yml`. While this package is `private`, `changeset version` still updates its `version` and `CHANGELOG.md`, but `changeset publish` skips it.
|
package/envelope.js
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
// Lazy decoder for the Rust↔JS raw-transfer envelope produced by
|
|
2
|
+
// `binding.compileEnvelope`. The byte format is owned by
|
|
3
|
+
// `src/napi_raw.rs`; keep both ends in sync.
|
|
4
|
+
//
|
|
5
|
+
// The returned object is shaped like the legacy `compile()` result
|
|
6
|
+
// (`{ js: { code, map }, css: {…}|null, warnings: […], metadata, ast }`)
|
|
7
|
+
// but its leaf strings, sourcemap JSON, and warnings array are
|
|
8
|
+
// realised on first read. That keeps the hot path (Vite reads
|
|
9
|
+
// `result.js.code` and `result.js.map`) down to two `Buffer.toString`
|
|
10
|
+
// calls and one `JSON.parse`, with no upfront V8 object tree
|
|
11
|
+
// construction.
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const MAGIC = 0x31565352; // "RSV1" little-endian
|
|
16
|
+
const VERSION = 1;
|
|
17
|
+
const HEADER_LEN = 60;
|
|
18
|
+
|
|
19
|
+
const FLAG_HAS_CSS = 1 << 0;
|
|
20
|
+
const FLAG_RUNES = 1 << 1;
|
|
21
|
+
const FLAG_CSS_HAS_GLOBAL = 1 << 2;
|
|
22
|
+
|
|
23
|
+
const WARN_HAS_FILENAME = 1 << 0;
|
|
24
|
+
const WARN_HAS_START = 1 << 1;
|
|
25
|
+
const WARN_HAS_END = 1 << 2;
|
|
26
|
+
const WARN_HAS_FRAME = 1 << 3;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Decode an envelope produced by `compileEnvelope` / `compileModuleEnvelope`.
|
|
30
|
+
*
|
|
31
|
+
* @param {Buffer|Uint8Array} buf
|
|
32
|
+
* @returns {object} CompileResult-shaped object with lazy fields
|
|
33
|
+
*/
|
|
34
|
+
function decodeEnvelope(buf) {
|
|
35
|
+
if (!buf || buf.byteLength < HEADER_LEN) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`[rsvelte] envelope too small (${buf ? buf.byteLength : 0} bytes, ` +
|
|
38
|
+
`expected at least ${HEADER_LEN})`,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
43
|
+
const magic = view.getUint32(0, true);
|
|
44
|
+
if (magic !== MAGIC) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`[rsvelte] envelope magic mismatch (got 0x${magic.toString(16)}, ` +
|
|
47
|
+
`expected 0x${MAGIC.toString(16)})`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const version = view.getUint32(4, true);
|
|
51
|
+
if (version !== VERSION) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`[rsvelte] unsupported envelope version ${version} (this build expects ${VERSION})`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
const totalLen = view.getUint32(8, true);
|
|
57
|
+
if (totalLen !== buf.byteLength) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`[rsvelte] envelope size mismatch (header says ${totalLen}, buffer is ${buf.byteLength})`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const flags = view.getUint32(12, true);
|
|
64
|
+
const jsCodeOff = view.getUint32(16, true);
|
|
65
|
+
const jsCodeLen = view.getUint32(20, true);
|
|
66
|
+
const jsMapOff = view.getUint32(24, true);
|
|
67
|
+
const jsMapLen = view.getUint32(28, true);
|
|
68
|
+
const cssCodeOff = view.getUint32(32, true);
|
|
69
|
+
const cssCodeLen = view.getUint32(36, true);
|
|
70
|
+
const cssMapOff = view.getUint32(40, true);
|
|
71
|
+
const cssMapLen = view.getUint32(44, true);
|
|
72
|
+
const warningsOff = view.getUint32(48, true);
|
|
73
|
+
const warningsCount = view.getUint32(52, true);
|
|
74
|
+
|
|
75
|
+
const hasCss = (flags & FLAG_HAS_CSS) !== 0;
|
|
76
|
+
const runes = (flags & FLAG_RUNES) !== 0;
|
|
77
|
+
|
|
78
|
+
// `buf.toString('utf8', start, end)` is the V8 fast path for
|
|
79
|
+
// Buffer→string and is consistently faster than wrapping in a
|
|
80
|
+
// TextDecoder; fall back to TextDecoder for plain Uint8Array.
|
|
81
|
+
const slice = bufferIsNodeBuffer(buf)
|
|
82
|
+
? (off, len) => buf.toString('utf8', off, off + len)
|
|
83
|
+
: utf8SliceFromUint8Array.bind(null, buf);
|
|
84
|
+
|
|
85
|
+
// js — eagerly construct the wrapper object, but defer string/JSON
|
|
86
|
+
// realisation. Vite always touches `js.code`; the map is only
|
|
87
|
+
// touched when emitting sourcemaps.
|
|
88
|
+
const js = makeCodeMapObject(buf, slice, jsCodeOff, jsCodeLen, jsMapOff, jsMapLen);
|
|
89
|
+
|
|
90
|
+
let css = null;
|
|
91
|
+
if (hasCss) {
|
|
92
|
+
css = makeCodeMapObject(buf, slice, cssCodeOff, cssCodeLen, cssMapOff, cssMapLen);
|
|
93
|
+
css.hasGlobal = (flags & FLAG_CSS_HAS_GLOBAL) !== 0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const result = {
|
|
97
|
+
js,
|
|
98
|
+
css,
|
|
99
|
+
metadata: { runes },
|
|
100
|
+
ast: null,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// Warnings: realised lazily — most compilations produce zero, so
|
|
104
|
+
// the common path never enters this branch. Once decoded, the
|
|
105
|
+
// result is cached.
|
|
106
|
+
let warningsCache = null;
|
|
107
|
+
Object.defineProperty(result, 'warnings', {
|
|
108
|
+
enumerable: true,
|
|
109
|
+
configurable: true,
|
|
110
|
+
get() {
|
|
111
|
+
if (warningsCache === null) {
|
|
112
|
+
warningsCache = decodeWarnings(buf, view, warningsOff, warningsCount, slice);
|
|
113
|
+
}
|
|
114
|
+
return warningsCache;
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function makeCodeMapObject(buf, slice, codeOff, codeLen, mapOff, mapLen) {
|
|
122
|
+
const obj = {};
|
|
123
|
+
let codeCache = null;
|
|
124
|
+
// `code` and `map` need setters as well as getters — upstream
|
|
125
|
+
// `svelte/compiler` returns them as plain writable strings, and
|
|
126
|
+
// vite-plugin-svelte mutates `compiled.js.code` to wire the CSS
|
|
127
|
+
// import (see compile.js:131, `compiled.js.code += ...`). Without
|
|
128
|
+
// a setter the assignment throws `Cannot set property code of
|
|
129
|
+
// #<Object> which has only a getter` under the strict-mode rolldown
|
|
130
|
+
// runtime and the docs build fails.
|
|
131
|
+
Object.defineProperty(obj, 'code', {
|
|
132
|
+
enumerable: true,
|
|
133
|
+
configurable: true,
|
|
134
|
+
get() {
|
|
135
|
+
if (codeCache === null) codeCache = slice(codeOff, codeLen);
|
|
136
|
+
return codeCache;
|
|
137
|
+
},
|
|
138
|
+
set(value) {
|
|
139
|
+
codeCache = value;
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
const hasMap = mapOff !== 0;
|
|
143
|
+
let mapCache = hasMap ? undefined : null;
|
|
144
|
+
Object.defineProperty(obj, 'map', {
|
|
145
|
+
enumerable: true,
|
|
146
|
+
configurable: true,
|
|
147
|
+
get() {
|
|
148
|
+
if (mapCache === undefined) {
|
|
149
|
+
// Parse the sourcemap JSON on first read. Returning the
|
|
150
|
+
// parsed object matches the legacy compile() shape —
|
|
151
|
+
// callers that just want the raw JSON to write to disk
|
|
152
|
+
// should prefer `mapBytes` / `mapText` (no JSON.parse).
|
|
153
|
+
mapCache = JSON.parse(slice(mapOff, mapLen));
|
|
154
|
+
}
|
|
155
|
+
return mapCache;
|
|
156
|
+
},
|
|
157
|
+
set(value) {
|
|
158
|
+
mapCache = value;
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
// `mapBytes` returns a zero-copy view into the envelope (Node Buffer
|
|
162
|
+
// or Uint8Array depending on what the caller passed in). Use this
|
|
163
|
+
// when emitting the sourcemap straight to disk / a network stream
|
|
164
|
+
// — no JSON.parse, no UTF-16 string materialisation.
|
|
165
|
+
Object.defineProperty(obj, 'mapBytes', {
|
|
166
|
+
enumerable: false,
|
|
167
|
+
configurable: true,
|
|
168
|
+
get() {
|
|
169
|
+
if (!hasMap) return null;
|
|
170
|
+
return buf.subarray
|
|
171
|
+
? buf.subarray(mapOff, mapOff + mapLen)
|
|
172
|
+
: new Uint8Array(buf.buffer, buf.byteOffset + mapOff, mapLen);
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
// `mapText` returns the raw sourcemap JSON as a string without the
|
|
176
|
+
// `JSON.parse` round-trip. Useful when downstream tooling immediately
|
|
177
|
+
// `JSON.stringify`s the map again (Vite's asset emit path).
|
|
178
|
+
Object.defineProperty(obj, 'mapText', {
|
|
179
|
+
enumerable: false,
|
|
180
|
+
configurable: true,
|
|
181
|
+
get() {
|
|
182
|
+
if (!hasMap) return null;
|
|
183
|
+
return slice(mapOff, mapLen);
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
return obj;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function decodeWarnings(buf, view, off, count, slice) {
|
|
190
|
+
const out = new Array(count);
|
|
191
|
+
let p = off;
|
|
192
|
+
for (let i = 0; i < count; i++) {
|
|
193
|
+
const codeLen = view.getUint32(p, true);
|
|
194
|
+
p += 4;
|
|
195
|
+
const code = slice(p, codeLen);
|
|
196
|
+
p += codeLen;
|
|
197
|
+
const msgLen = view.getUint32(p, true);
|
|
198
|
+
p += 4;
|
|
199
|
+
const message = slice(p, msgLen);
|
|
200
|
+
p += msgLen;
|
|
201
|
+
const flags = view.getUint8(p);
|
|
202
|
+
p += 1;
|
|
203
|
+
|
|
204
|
+
const w = { code, message };
|
|
205
|
+
if (flags & WARN_HAS_FILENAME) {
|
|
206
|
+
const len = view.getUint32(p, true);
|
|
207
|
+
p += 4;
|
|
208
|
+
w.filename = slice(p, len);
|
|
209
|
+
p += len;
|
|
210
|
+
}
|
|
211
|
+
if (flags & WARN_HAS_START) {
|
|
212
|
+
w.start = {
|
|
213
|
+
line: view.getUint32(p, true),
|
|
214
|
+
column: view.getUint32(p + 4, true),
|
|
215
|
+
character: view.getUint32(p + 8, true),
|
|
216
|
+
};
|
|
217
|
+
p += 12;
|
|
218
|
+
}
|
|
219
|
+
if (flags & WARN_HAS_END) {
|
|
220
|
+
w.end = {
|
|
221
|
+
line: view.getUint32(p, true),
|
|
222
|
+
column: view.getUint32(p + 4, true),
|
|
223
|
+
character: view.getUint32(p + 8, true),
|
|
224
|
+
};
|
|
225
|
+
p += 12;
|
|
226
|
+
}
|
|
227
|
+
if (w.start && w.end) {
|
|
228
|
+
w.position = [w.start.character, w.end.character];
|
|
229
|
+
}
|
|
230
|
+
if (flags & WARN_HAS_FRAME) {
|
|
231
|
+
const len = view.getUint32(p, true);
|
|
232
|
+
p += 4;
|
|
233
|
+
w.frame = slice(p, len);
|
|
234
|
+
p += len;
|
|
235
|
+
}
|
|
236
|
+
out[i] = w;
|
|
237
|
+
}
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function bufferIsNodeBuffer(buf) {
|
|
242
|
+
return typeof Buffer !== 'undefined' && Buffer.isBuffer(buf);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
let cachedDecoder = null;
|
|
246
|
+
function utf8SliceFromUint8Array(u8, off, len) {
|
|
247
|
+
if (cachedDecoder === null) cachedDecoder = new TextDecoder('utf-8');
|
|
248
|
+
return cachedDecoder.decode(u8.subarray(off, off + len));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// =============================================================================
|
|
252
|
+
// Batch envelope
|
|
253
|
+
// =============================================================================
|
|
254
|
+
|
|
255
|
+
const BATCH_MAGIC = 0x42565352; // "RSVB" little-endian
|
|
256
|
+
const BATCH_VERSION = 1;
|
|
257
|
+
const BATCH_HEADER_LEN = 16;
|
|
258
|
+
const BATCH_ENTRY_LEN = 12;
|
|
259
|
+
const BATCH_STATUS_OK = 0;
|
|
260
|
+
const BATCH_STATUS_ERR = 1;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Decode a batch envelope produced by `compileBatch`. Returns an
|
|
264
|
+
* array the same length as the input, where each slot is either a
|
|
265
|
+
* `CompileResult` (decoded lazily on first read, like {@link decodeEnvelope})
|
|
266
|
+
* or an `Error` carrying the per-entry failure message.
|
|
267
|
+
*
|
|
268
|
+
* @param {Buffer|Uint8Array} buf
|
|
269
|
+
* @returns {Array<object|Error>}
|
|
270
|
+
*/
|
|
271
|
+
function decodeBatch(buf) {
|
|
272
|
+
if (!buf || buf.byteLength < BATCH_HEADER_LEN) {
|
|
273
|
+
throw new Error(
|
|
274
|
+
`[rsvelte] batch envelope too small (${buf ? buf.byteLength : 0} bytes, ` +
|
|
275
|
+
`expected at least ${BATCH_HEADER_LEN})`,
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
280
|
+
const magic = view.getUint32(0, true);
|
|
281
|
+
if (magic !== BATCH_MAGIC) {
|
|
282
|
+
throw new Error(
|
|
283
|
+
`[rsvelte] batch magic mismatch (got 0x${magic.toString(16)}, ` +
|
|
284
|
+
`expected 0x${BATCH_MAGIC.toString(16)})`,
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
const version = view.getUint32(4, true);
|
|
288
|
+
if (version !== BATCH_VERSION) {
|
|
289
|
+
throw new Error(
|
|
290
|
+
`[rsvelte] unsupported batch envelope version ${version} (this build expects ${BATCH_VERSION})`,
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
const totalLen = view.getUint32(8, true);
|
|
294
|
+
if (totalLen !== buf.byteLength) {
|
|
295
|
+
throw new Error(
|
|
296
|
+
`[rsvelte] batch envelope size mismatch (header says ${totalLen}, buffer is ${buf.byteLength})`,
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
const count = view.getUint32(12, true);
|
|
300
|
+
|
|
301
|
+
const out = new Array(count);
|
|
302
|
+
for (let i = 0; i < count; i++) {
|
|
303
|
+
const entryOff = BATCH_HEADER_LEN + i * BATCH_ENTRY_LEN;
|
|
304
|
+
const status = view.getUint32(entryOff, true);
|
|
305
|
+
const payloadOff = view.getUint32(entryOff + 4, true);
|
|
306
|
+
const payloadLen = view.getUint32(entryOff + 8, true);
|
|
307
|
+
// Subarray gives a zero-copy view into the same underlying
|
|
308
|
+
// ArrayBuffer; `decodeEnvelope` walks it without further allocation.
|
|
309
|
+
const slice = buf.subarray
|
|
310
|
+
? buf.subarray(payloadOff, payloadOff + payloadLen)
|
|
311
|
+
: new Uint8Array(buf.buffer, buf.byteOffset + payloadOff, payloadLen);
|
|
312
|
+
if (status === BATCH_STATUS_OK) {
|
|
313
|
+
out[i] = decodeEnvelope(slice);
|
|
314
|
+
} else if (status === BATCH_STATUS_ERR) {
|
|
315
|
+
const msg = bufferIsNodeBuffer(slice)
|
|
316
|
+
? slice.toString('utf8')
|
|
317
|
+
: utf8SliceFromUint8Array(slice, 0, slice.byteLength);
|
|
318
|
+
out[i] = new Error(msg);
|
|
319
|
+
} else {
|
|
320
|
+
out[i] = new Error(`[rsvelte] unknown batch entry status ${status} at index ${i}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return out;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
module.exports = {
|
|
327
|
+
decodeEnvelope,
|
|
328
|
+
decodeBatch,
|
|
329
|
+
HEADER_LEN,
|
|
330
|
+
MAGIC,
|
|
331
|
+
VERSION,
|
|
332
|
+
BATCH_HEADER_LEN,
|
|
333
|
+
BATCH_MAGIC,
|
|
334
|
+
BATCH_VERSION,
|
|
335
|
+
};
|
package/index.cjs
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Resolve the rsvelte NAPI binding for the current platform and re-export it.
|
|
2
|
+
// Mirrors the loader pattern napi-rs generates: resolve a platform-specific
|
|
3
|
+
// dependency that ships a single `rsvelte.node` artifact.
|
|
4
|
+
|
|
5
|
+
const { decodeEnvelope, decodeBatch } = require('./envelope.js');
|
|
6
|
+
|
|
7
|
+
const { platform, arch } = process;
|
|
8
|
+
|
|
9
|
+
function resolveTriple() {
|
|
10
|
+
if (platform === 'darwin') {
|
|
11
|
+
if (arch === 'arm64') return 'darwin-arm64';
|
|
12
|
+
if (arch === 'x64') return 'darwin-x64';
|
|
13
|
+
} else if (platform === 'linux') {
|
|
14
|
+
// Node 18+ exposes the runtime glibc version in the report header. An
|
|
15
|
+
// empty value means we're on musl (Alpine, distroless, etc.).
|
|
16
|
+
let isMusl = false;
|
|
17
|
+
try {
|
|
18
|
+
const header = process.report.getReport().header;
|
|
19
|
+
isMusl = !header.glibcVersionRuntime;
|
|
20
|
+
} catch {
|
|
21
|
+
isMusl = false;
|
|
22
|
+
}
|
|
23
|
+
const libc = isMusl ? 'musl' : 'gnu';
|
|
24
|
+
if (arch === 'x64') return `linux-x64-${libc}`;
|
|
25
|
+
if (arch === 'arm64') return `linux-arm64-${libc}`;
|
|
26
|
+
} else if (platform === 'win32') {
|
|
27
|
+
if (arch === 'x64') return 'win32-x64-msvc';
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const triple = resolveTriple();
|
|
33
|
+
if (!triple) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`[@rsvelte/vite-plugin-svelte-native] Unsupported platform: ${platform}-${arch}. ` +
|
|
36
|
+
`Open an issue at https://github.com/baseballyama/rsvelte/issues if you'd like it supported.`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const pkgName = `@rsvelte/vite-plugin-svelte-native-${triple}`;
|
|
41
|
+
let binding;
|
|
42
|
+
try {
|
|
43
|
+
binding = require(`${pkgName}/rsvelte.node`);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`[@rsvelte/vite-plugin-svelte-native] Couldn't load the native binding "${pkgName}".\n` +
|
|
47
|
+
`This usually means npm/pnpm skipped the optional dependency for your platform.\n` +
|
|
48
|
+
`Try reinstalling: npm install --include=optional ${pkgName}\n\n` +
|
|
49
|
+
`Original error: ${err.message}`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// `compile` / `compileModule` are wrapped to route through the
|
|
54
|
+
// raw-transfer envelope (`compileEnvelope`): the Rust side hands us
|
|
55
|
+
// one `Buffer`, the JS side lazy-decodes only the fields the caller
|
|
56
|
+
// reads. This avoids the V8 string copy + `serde_json` round-trip
|
|
57
|
+
// that the legacy JSON path pays for every call.
|
|
58
|
+
//
|
|
59
|
+
// Callers that need the raw envelope (e.g. to ship it across a worker
|
|
60
|
+
// boundary without re-encoding) can still grab `binding.compileEnvelope`
|
|
61
|
+
// directly. The legacy JSON path is preserved as `compileLegacy` for
|
|
62
|
+
// parity testing and as an escape hatch.
|
|
63
|
+
function compile(source, options) {
|
|
64
|
+
return decodeEnvelope(binding.compileEnvelope(source, options));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function compileModule(source, options) {
|
|
68
|
+
return decodeEnvelope(binding.compileModuleEnvelope(source, options));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// `compileBatch([{source, options}, …])` compiles N files in
|
|
72
|
+
// parallel (rayon on the Rust side) and crosses the NAPI boundary
|
|
73
|
+
// exactly once. The returned array is the same length as the input;
|
|
74
|
+
// each slot is either a `CompileResult` or an `Error` (parse
|
|
75
|
+
// failures don't abort the whole batch).
|
|
76
|
+
function compileBatch(inputs) {
|
|
77
|
+
return decodeBatch(binding.compileBatch(inputs));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// `compileAsync` / `compileBatchAsync` release the JS event loop
|
|
81
|
+
// while the Rust side compiles on a libuv worker thread. Useful
|
|
82
|
+
// for plugins that interleave compilation with other async work
|
|
83
|
+
// (Vite middleware, SSR pre-render) — the await yields control
|
|
84
|
+
// instead of blocking V8.
|
|
85
|
+
async function compileAsync(source, options) {
|
|
86
|
+
return decodeEnvelope(await binding.compileEnvelopeAsync(source, options));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function compileBatchAsync(inputs) {
|
|
90
|
+
return decodeBatch(await binding.compileBatchAsync(inputs));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Re-export every NAPI function as its own named binding so node's
|
|
94
|
+
// `cjs-module-lexer` can pick them up when this file is imported via
|
|
95
|
+
// ESM (e.g. `import { compile, preprocess, VERSION } from …`). A bare
|
|
96
|
+
// `module.exports = binding` would only expose the default export
|
|
97
|
+
// reliably; explicit `module.exports.X = …` lines are what the lexer
|
|
98
|
+
// scans for.
|
|
99
|
+
//
|
|
100
|
+
// The static list mirrors `src/napi.rs`'s `#[napi(js_name = ...)]`
|
|
101
|
+
// attributes — keep it in sync when adding/removing NAPI exports.
|
|
102
|
+
module.exports.compile = compile;
|
|
103
|
+
module.exports.compileModule = compileModule;
|
|
104
|
+
module.exports.compileLegacy = binding.compile;
|
|
105
|
+
module.exports.compileModuleLegacy = binding.compileModule;
|
|
106
|
+
module.exports.compileEnvelope = binding.compileEnvelope;
|
|
107
|
+
module.exports.compileModuleEnvelope = binding.compileModuleEnvelope;
|
|
108
|
+
// Zero-copy variants: same envelope format, but the returned Buffer
|
|
109
|
+
// is a view into bumpalo arena memory (no Vec copy). Use these when
|
|
110
|
+
// you know the buffer will be consumed once and discarded — the
|
|
111
|
+
// arena is freed when the Buffer is GC'd. For long-lived buffers
|
|
112
|
+
// passed across worker boundaries, prefer `compileEnvelope` which
|
|
113
|
+
// hands you an owned Vec.
|
|
114
|
+
module.exports.compileEnvelopeZeroCopy = binding.compileEnvelopeZeroCopy;
|
|
115
|
+
module.exports.compileModuleEnvelopeZeroCopy = binding.compileModuleEnvelopeZeroCopy;
|
|
116
|
+
module.exports.compileBuffers = binding.compileBuffers;
|
|
117
|
+
module.exports.compileModuleBuffers = binding.compileModuleBuffers;
|
|
118
|
+
module.exports.compileBatch = compileBatch;
|
|
119
|
+
module.exports.compileBatchRaw = binding.compileBatch;
|
|
120
|
+
module.exports.compileAsync = compileAsync;
|
|
121
|
+
module.exports.compileBatchAsync = compileBatchAsync;
|
|
122
|
+
module.exports.compileEnvelopeAsync = binding.compileEnvelopeAsync;
|
|
123
|
+
module.exports.compileBatchAsyncRaw = binding.compileBatchAsync;
|
|
124
|
+
module.exports.decodeEnvelope = decodeEnvelope;
|
|
125
|
+
module.exports.decodeBatch = decodeBatch;
|
|
126
|
+
module.exports.preprocess = binding.preprocess;
|
|
127
|
+
module.exports.svelte2tsx = binding.svelte2tsx;
|
|
128
|
+
module.exports.hmrDiff = binding.hmrDiff;
|
|
129
|
+
module.exports.resolveId = binding.resolveId;
|
|
130
|
+
// Upstream Svelte version this binding emits code for — used by
|
|
131
|
+
// downstream consumers (the `@rsvelte/vite-plugin-svelte` fork, etc.)
|
|
132
|
+
// for `gte(VERSION, '5.36.0')`-style feature detection. Synced
|
|
133
|
+
// manually against `submodules/svelte/packages/svelte/package.json`.
|
|
134
|
+
module.exports.VERSION = '5.51.3';
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
// Public surface of the rsvelte NAPI binding. Mirrors the `#[napi]` exports in
|
|
2
|
+
// `src/napi.rs`. The structural types below match the upstream Svelte
|
|
3
|
+
// (`svelte/compiler`) names where they map cleanly, so consumers — including
|
|
4
|
+
// the `@rsvelte/vite-plugin-svelte` fork — can stay drop-in compatible with
|
|
5
|
+
// the official surface.
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Options
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Component compile options. Loosely follows `svelte/compiler#CompileOptions`.
|
|
13
|
+
*/
|
|
14
|
+
export interface CompileOptions {
|
|
15
|
+
/** Enable dev mode (instrumentation, warnings, etc.). */
|
|
16
|
+
dev?: boolean;
|
|
17
|
+
/** Generate client- or server-side code, or skip codegen. */
|
|
18
|
+
generate?: 'client' | 'server' | false;
|
|
19
|
+
/** Source filename. Used in source maps and error frames. */
|
|
20
|
+
filename?: string;
|
|
21
|
+
/** Project root, used to compute relative source-map paths. */
|
|
22
|
+
rootDir?: string;
|
|
23
|
+
/** Component identifier hint. */
|
|
24
|
+
name?: string;
|
|
25
|
+
/** Compile as a custom element. */
|
|
26
|
+
customElement?: boolean;
|
|
27
|
+
/** Generate `accessors`. */
|
|
28
|
+
accessors?: boolean;
|
|
29
|
+
/** HTML namespace. */
|
|
30
|
+
namespace?: 'html' | 'svg' | 'mathml';
|
|
31
|
+
/** Hint that bindings are immutable. */
|
|
32
|
+
immutable?: boolean;
|
|
33
|
+
/** Output CSS injected into the bundle or as an external asset. */
|
|
34
|
+
css?: 'injected' | 'external';
|
|
35
|
+
/** Custom hash function for CSS scoping — currently honored as a string-mapper. */
|
|
36
|
+
cssHash?: (args: {
|
|
37
|
+
hash: (input: string) => string;
|
|
38
|
+
css: string;
|
|
39
|
+
name: string;
|
|
40
|
+
filename: string | undefined;
|
|
41
|
+
}) => string;
|
|
42
|
+
/** Preserve HTML comments in output. */
|
|
43
|
+
preserveComments?: boolean;
|
|
44
|
+
/** Preserve whitespace in the template. */
|
|
45
|
+
preserveWhitespace?: boolean;
|
|
46
|
+
/** Force runes mode (`true`), legacy (`false`), or auto-detect (`undefined`). */
|
|
47
|
+
runes?: boolean;
|
|
48
|
+
/** Disclose the compiler version in the output banner. */
|
|
49
|
+
discloseVersion?: boolean;
|
|
50
|
+
/** Source-map options (forwarded through magic-string). */
|
|
51
|
+
sourcemap?: object | string;
|
|
52
|
+
/** Output JS filename for `file` in the JS source map. */
|
|
53
|
+
outputFilename?: string;
|
|
54
|
+
/** Output CSS filename for `file` in the CSS source map. */
|
|
55
|
+
cssOutputFilename?: string;
|
|
56
|
+
/** Enable HMR-friendly output (used by `@rsvelte/vite-plugin-svelte`). */
|
|
57
|
+
hmr?: boolean;
|
|
58
|
+
/** Emit the modern AST shape (default). */
|
|
59
|
+
modernAst?: boolean;
|
|
60
|
+
/** Filter compiler warnings. */
|
|
61
|
+
warningFilter?: (warning: Warning) => boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Module compile options. Subset of {@link CompileOptions} that applies to
|
|
66
|
+
* `.svelte.js` / `.svelte.ts` modules.
|
|
67
|
+
*/
|
|
68
|
+
export interface ModuleCompileOptions {
|
|
69
|
+
dev?: boolean;
|
|
70
|
+
generate?: 'client' | 'server' | false;
|
|
71
|
+
filename?: string;
|
|
72
|
+
rootDir?: string;
|
|
73
|
+
warningFilter?: (warning: Warning) => boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Diagnostics
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
export interface SourcePosition {
|
|
81
|
+
line: number;
|
|
82
|
+
column: number;
|
|
83
|
+
character: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Compiler warning matching `svelte/compiler#Warning`. */
|
|
87
|
+
export interface Warning {
|
|
88
|
+
code: string;
|
|
89
|
+
message: string;
|
|
90
|
+
filename?: string;
|
|
91
|
+
start?: SourcePosition;
|
|
92
|
+
end?: SourcePosition;
|
|
93
|
+
position?: [number, number];
|
|
94
|
+
frame?: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Compile result
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
export interface CompileResultJs {
|
|
102
|
+
code: string;
|
|
103
|
+
/**
|
|
104
|
+
* A standard SourceMap v3 JSON object. Accessing this triggers a
|
|
105
|
+
* one-time `JSON.parse` of the underlying envelope bytes. For
|
|
106
|
+
* callers that immediately re-serialize (writing to disk,
|
|
107
|
+
* sending over the wire) prefer {@link mapBytes} / {@link mapText}
|
|
108
|
+
* to skip the parse round-trip.
|
|
109
|
+
*/
|
|
110
|
+
map: unknown;
|
|
111
|
+
/**
|
|
112
|
+
* Zero-copy `Buffer` / `Uint8Array` view over the raw sourcemap
|
|
113
|
+
* JSON bytes in the envelope. `null` if no map was produced. Stable
|
|
114
|
+
* for the lifetime of the parent `CompileResult` (becomes invalid
|
|
115
|
+
* once a `compileEnvelopeZeroCopy` buffer is GC'd).
|
|
116
|
+
*/
|
|
117
|
+
mapBytes: Buffer | Uint8Array | null;
|
|
118
|
+
/** Raw sourcemap JSON as a string — no `JSON.parse`. `null` if no map. */
|
|
119
|
+
mapText: string | null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface CompileResultCss {
|
|
123
|
+
code: string;
|
|
124
|
+
/** See {@link CompileResultJs.map}. */
|
|
125
|
+
map: unknown;
|
|
126
|
+
mapBytes: Buffer | Uint8Array | null;
|
|
127
|
+
mapText: string | null;
|
|
128
|
+
hasGlobal: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface CompileResult {
|
|
132
|
+
js: CompileResultJs;
|
|
133
|
+
css: CompileResultCss | null;
|
|
134
|
+
warnings: Warning[];
|
|
135
|
+
metadata: { runes?: boolean } & Record<string, unknown>;
|
|
136
|
+
ast: unknown;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Compile a Svelte component. Internally goes through the raw-transfer
|
|
141
|
+
* envelope (`compileEnvelope` + `decodeEnvelope`) so that heavy strings
|
|
142
|
+
* (generated code, sourcemap JSON) are read out of the underlying
|
|
143
|
+
* `Buffer` only when the caller touches `.code` / `.map`. The shape
|
|
144
|
+
* matches `svelte/compiler#compile`.
|
|
145
|
+
*/
|
|
146
|
+
export function compile(source: string, options?: CompileOptions): CompileResult;
|
|
147
|
+
export function compileModule(
|
|
148
|
+
source: string,
|
|
149
|
+
options?: ModuleCompileOptions,
|
|
150
|
+
): CompileResult;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Lower-level raw-transfer entry point. Returns a single `Buffer`
|
|
154
|
+
* containing the entire compile result in the rsvelte envelope format
|
|
155
|
+
* (see `src/napi_raw.rs`). Pair with {@link decodeEnvelope} to obtain
|
|
156
|
+
* the legacy {@link CompileResult} shape; or pass the buffer through
|
|
157
|
+
* worker `postMessage` (transferable) to avoid a copy.
|
|
158
|
+
*/
|
|
159
|
+
export function compileEnvelope(source: string, options?: CompileOptions): Buffer;
|
|
160
|
+
export function compileModuleEnvelope(
|
|
161
|
+
source: string,
|
|
162
|
+
options?: ModuleCompileOptions,
|
|
163
|
+
): Buffer;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Zero-copy variant. Returns a `Buffer` view over `bumpalo` arena
|
|
167
|
+
* memory rather than an owned `Vec<u8>` — no copy whatsoever at the
|
|
168
|
+
* Rust↔JS boundary. The arena is freed when V8 garbage-collects the
|
|
169
|
+
* Buffer, so the data stays valid for as long as JS holds a reference.
|
|
170
|
+
*
|
|
171
|
+
* Trade-offs vs {@link compileEnvelope}:
|
|
172
|
+
*
|
|
173
|
+
* - **Faster:** skips Rust's `Vec` allocation; pre-sized arena slice.
|
|
174
|
+
* - **Limited transferability:** if you `postMessage` the buffer with
|
|
175
|
+
* `transfer:` between workers, V8 may need to detach the underlying
|
|
176
|
+
* storage. The arena finalizer only runs when V8 actually GCs the
|
|
177
|
+
* Buffer wrapper, so detach semantics are safe but may surprise
|
|
178
|
+
* callers used to `Buffer` semantics.
|
|
179
|
+
*/
|
|
180
|
+
export function compileEnvelopeZeroCopy(
|
|
181
|
+
source: string,
|
|
182
|
+
options?: CompileOptions,
|
|
183
|
+
): Buffer;
|
|
184
|
+
export function compileModuleEnvelopeZeroCopy(
|
|
185
|
+
source: string,
|
|
186
|
+
options?: ModuleCompileOptions,
|
|
187
|
+
): Buffer;
|
|
188
|
+
|
|
189
|
+
/** Decode a buffer produced by {@link compileEnvelope}. */
|
|
190
|
+
export function decodeEnvelope(buf: Buffer | Uint8Array): CompileResult;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Single entry in a {@link compileBatch} worklist. `options` is
|
|
194
|
+
* forwarded to the underlying compile as if you had called
|
|
195
|
+
* `compile(source, options)`.
|
|
196
|
+
*/
|
|
197
|
+
export interface CompileBatchInput {
|
|
198
|
+
source: string;
|
|
199
|
+
options?: CompileOptions;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Compile multiple Svelte components in one NAPI call. The Rust side
|
|
204
|
+
* dispatches across rayon workers; the JS side gets one `Buffer`
|
|
205
|
+
* back containing all N results. Per-entry failures surface as
|
|
206
|
+
* `Error` instances at the corresponding slot — they don't abort
|
|
207
|
+
* the rest of the batch.
|
|
208
|
+
*
|
|
209
|
+
* Use this when you'd otherwise loop `compile()` over many files
|
|
210
|
+
* (Vite dev server, SSR pre-render). For one-off compiles the
|
|
211
|
+
* per-call overhead of `compile()` is already small.
|
|
212
|
+
*/
|
|
213
|
+
export function compileBatch(
|
|
214
|
+
inputs: CompileBatchInput[],
|
|
215
|
+
): Array<CompileResult | Error>;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Lower-level entry point: returns the raw batch envelope as a single
|
|
219
|
+
* `Buffer`. Pair with {@link decodeBatch} to obtain the same array
|
|
220
|
+
* {@link compileBatch} would, or pass through worker `postMessage`.
|
|
221
|
+
*/
|
|
222
|
+
export function compileBatchRaw(inputs: CompileBatchInput[]): Buffer;
|
|
223
|
+
|
|
224
|
+
/** Decode a batch envelope produced by {@link compileBatchRaw}. */
|
|
225
|
+
export function decodeBatch(buf: Buffer | Uint8Array): Array<CompileResult | Error>;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Async variant of {@link compile}. The Rust side runs on a libuv
|
|
229
|
+
* worker thread; the JS thread stays free to handle other callbacks.
|
|
230
|
+
* Returned `Promise<CompileResult>` resolves when the envelope has
|
|
231
|
+
* been encoded and decoded.
|
|
232
|
+
*/
|
|
233
|
+
export function compileAsync(
|
|
234
|
+
source: string,
|
|
235
|
+
options?: CompileOptions,
|
|
236
|
+
): Promise<CompileResult>;
|
|
237
|
+
|
|
238
|
+
/** Async variant of {@link compileBatch}. */
|
|
239
|
+
export function compileBatchAsync(
|
|
240
|
+
inputs: CompileBatchInput[],
|
|
241
|
+
): Promise<Array<CompileResult | Error>>;
|
|
242
|
+
|
|
243
|
+
/** Lower-level: returns `Promise<Buffer>` (the raw envelope). */
|
|
244
|
+
export function compileEnvelopeAsync(
|
|
245
|
+
source: string,
|
|
246
|
+
options?: CompileOptions,
|
|
247
|
+
): Promise<Buffer>;
|
|
248
|
+
|
|
249
|
+
/** Lower-level: returns `Promise<Buffer>` (the raw batch envelope). */
|
|
250
|
+
export function compileBatchAsyncRaw(inputs: CompileBatchInput[]): Promise<Buffer>;
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Step-1 variant of {@link compile}: returns the same shape but with
|
|
254
|
+
* `js.code` / `js.map` / `css.code` / `css.map` as raw `Buffer`s. The
|
|
255
|
+
* envelope path ({@link compile}) supersedes this for most callers; it
|
|
256
|
+
* stays exported as an escape hatch for callers that want structured
|
|
257
|
+
* access without the envelope decode.
|
|
258
|
+
*/
|
|
259
|
+
export interface CompileBuffersResult {
|
|
260
|
+
js: { code: Buffer; map: Buffer | null };
|
|
261
|
+
css: { code: Buffer; map: Buffer | null; hasGlobal: boolean } | null;
|
|
262
|
+
warnings: Warning[];
|
|
263
|
+
runes: boolean;
|
|
264
|
+
}
|
|
265
|
+
export function compileBuffers(
|
|
266
|
+
source: string,
|
|
267
|
+
options?: CompileOptions,
|
|
268
|
+
): CompileBuffersResult;
|
|
269
|
+
export function compileModuleBuffers(
|
|
270
|
+
source: string,
|
|
271
|
+
options?: ModuleCompileOptions,
|
|
272
|
+
): CompileBuffersResult;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* The legacy JSON-on-the-boundary path. Kept exported for parity tests
|
|
276
|
+
* and as an escape hatch — production callers should use {@link compile}.
|
|
277
|
+
*/
|
|
278
|
+
export function compileLegacy(source: string, options?: CompileOptions): CompileResult;
|
|
279
|
+
export function compileModuleLegacy(
|
|
280
|
+
source: string,
|
|
281
|
+
options?: ModuleCompileOptions,
|
|
282
|
+
): CompileResult;
|
|
283
|
+
|
|
284
|
+
// ---------------------------------------------------------------------------
|
|
285
|
+
// svelte2tsx
|
|
286
|
+
// ---------------------------------------------------------------------------
|
|
287
|
+
|
|
288
|
+
export interface Svelte2TsxResult {
|
|
289
|
+
code: string;
|
|
290
|
+
map: unknown;
|
|
291
|
+
exportedNames: { props: string[]; all: string[] };
|
|
292
|
+
events: Record<string, unknown>;
|
|
293
|
+
}
|
|
294
|
+
export function svelte2tsx(
|
|
295
|
+
source: string,
|
|
296
|
+
options?: Record<string, unknown>,
|
|
297
|
+
): Svelte2TsxResult;
|
|
298
|
+
|
|
299
|
+
// ---------------------------------------------------------------------------
|
|
300
|
+
// HMR / resolver
|
|
301
|
+
// ---------------------------------------------------------------------------
|
|
302
|
+
|
|
303
|
+
export interface HmrDiff {
|
|
304
|
+
change: 'hot-update' | 'full-reload' | 'unchanged';
|
|
305
|
+
instanceChanged: boolean;
|
|
306
|
+
moduleChanged: boolean;
|
|
307
|
+
}
|
|
308
|
+
export function hmrDiff(prev: string, curr: string): HmrDiff;
|
|
309
|
+
|
|
310
|
+
export function resolveId(
|
|
311
|
+
importee: string,
|
|
312
|
+
importer: string | null | undefined,
|
|
313
|
+
options?: Record<string, unknown>,
|
|
314
|
+
): string | null;
|
|
315
|
+
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
// Preprocess
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
|
|
320
|
+
/** Options the preprocessor pipeline forwards to each callback. */
|
|
321
|
+
export interface MarkupPreprocessorOptions {
|
|
322
|
+
content: string;
|
|
323
|
+
filename?: string;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export interface PreprocessorOptions {
|
|
327
|
+
content: string;
|
|
328
|
+
filename?: string;
|
|
329
|
+
attributes: Record<string, string | boolean>;
|
|
330
|
+
markup?: string;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Result returned by a preprocessor callback. `undefined`/`null` is a no-op. */
|
|
334
|
+
export interface Processed {
|
|
335
|
+
code: string;
|
|
336
|
+
map?: string | object;
|
|
337
|
+
dependencies?: string[];
|
|
338
|
+
attributes?: Record<string, string | boolean>;
|
|
339
|
+
toString?: () => string;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export type MarkupPreprocessor = (
|
|
343
|
+
options: MarkupPreprocessorOptions,
|
|
344
|
+
) => Processed | void | null | undefined | Promise<Processed | void | null | undefined>;
|
|
345
|
+
|
|
346
|
+
export type Preprocessor = (
|
|
347
|
+
options: PreprocessorOptions,
|
|
348
|
+
) => Processed | void | null | undefined | Promise<Processed | void | null | undefined>;
|
|
349
|
+
|
|
350
|
+
export interface PreprocessorGroup {
|
|
351
|
+
name?: string;
|
|
352
|
+
markup?: MarkupPreprocessor;
|
|
353
|
+
script?: Preprocessor;
|
|
354
|
+
style?: Preprocessor;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Run the preprocessor pipeline. Accepts a single group or an array of
|
|
359
|
+
* groups, matching the upstream `svelte/compiler#preprocess` contract.
|
|
360
|
+
*/
|
|
361
|
+
export function preprocess(
|
|
362
|
+
source: string,
|
|
363
|
+
groups: PreprocessorGroup | PreprocessorGroup[],
|
|
364
|
+
options?: { filename?: string },
|
|
365
|
+
): Promise<Processed>;
|
|
366
|
+
|
|
367
|
+
// ---------------------------------------------------------------------------
|
|
368
|
+
// Version
|
|
369
|
+
// ---------------------------------------------------------------------------
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Upstream Svelte version this binding emits code for. Consumers (the
|
|
373
|
+
* `@rsvelte/vite-plugin-svelte` fork, etc.) use this for feature
|
|
374
|
+
* detection (`gte(VERSION, '5.36.0')`), so it follows the *upstream*
|
|
375
|
+
* Svelte semver — not the rsvelte version.
|
|
376
|
+
*/
|
|
377
|
+
export const VERSION: string;
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rsvelte/vite-plugin-svelte-native",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "NAPI bindings to the rsvelte compiler — used by the @rsvelte vite-plugin-svelte shim",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/baseballyama/rsvelte.git",
|
|
9
|
+
"directory": "npm/vite-plugin-svelte-native"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/baseballyama/rsvelte/tree/main/npm/vite-plugin-svelte-native#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/baseballyama/rsvelte/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"svelte",
|
|
17
|
+
"vite",
|
|
18
|
+
"vite-plugin",
|
|
19
|
+
"rust",
|
|
20
|
+
"napi"
|
|
21
|
+
],
|
|
22
|
+
"main": "./index.cjs",
|
|
23
|
+
"types": "./index.d.ts",
|
|
24
|
+
"files": [
|
|
25
|
+
"envelope.js",
|
|
26
|
+
"index.cjs",
|
|
27
|
+
"index.d.ts"
|
|
28
|
+
],
|
|
29
|
+
"optionalDependencies": {
|
|
30
|
+
"@rsvelte/vite-plugin-svelte-native-darwin-arm64": "^0.1.0",
|
|
31
|
+
"@rsvelte/vite-plugin-svelte-native-linux-x64-gnu": "^0.1.0",
|
|
32
|
+
"@rsvelte/vite-plugin-svelte-native-linux-arm64-gnu": "^0.1.0",
|
|
33
|
+
"@rsvelte/vite-plugin-svelte-native-darwin-x64": "^0.1.0",
|
|
34
|
+
"@rsvelte/vite-plugin-svelte-native-win32-x64-msvc": "^0.1.0"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
}
|
|
39
|
+
}
|