@rsvelte/vite-plugin-svelte-native 0.3.7 → 0.3.9

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/index.cjs CHANGED
@@ -54,32 +54,6 @@ function prepareCompileOptions(options) {
54
54
  return { options: resolved, warningFilter: hasWarningFilter ? warningFilter : undefined };
55
55
  }
56
56
 
57
- // Port of Svelte's `hash()` (submodules/svelte/packages/svelte/src/utils.js),
58
- // handed to a user `cssHash` callback so custom scope classes match upstream's digest.
59
- const regexReturnCharacters = /\r/g;
60
- function hash(str) {
61
- str = str.replace(regexReturnCharacters, '');
62
- let h = 5381;
63
- let i = str.length;
64
- while (i--) h = ((h << 5) - h) ^ str.charCodeAt(i);
65
- return (h >>> 0).toString(36);
66
- }
67
-
68
- // Adapt a user `cssHash` to the bridge shape. It must never reject: a rejected
69
- // Promise crossing the NAPI boundary can crash V8 during threadsafe-function
70
- // teardown — so a throw becomes `{ error }` (Rust turns it into a compile failure)
71
- // and a non-string return becomes `{ value: null }` (Rust falls back to the default hash).
72
- function makeCssHashCallback(userCssHash) {
73
- return async (name, filename, css) => {
74
- try {
75
- const result = await userCssHash({ hash, css, name, filename });
76
- return { value: typeof result === 'string' ? result : null };
77
- } catch (err) {
78
- return { error: err instanceof Error ? err.message : String(err) };
79
- }
80
- };
81
- }
82
-
83
57
  function applyWarningFilter(result, warningFilter) {
84
58
  if (!warningFilter || result == null) return result;
85
59
  const warnings = result.warnings;
@@ -183,11 +157,9 @@ async function compileAsync(source, options) {
183
157
  const { options: resolved, warningFilter } = prepareCompileOptions(options);
184
158
  if (typeof options?.cssHash === 'function') {
185
159
  // The bridge entry returns a plain (JSON) CompileResult, not an envelope.
186
- const result = await binding.compileWithCssHash(
187
- source,
188
- resolved,
189
- makeCssHashCallback(options.cssHash),
190
- );
160
+ // The callback is handed straight through: Rust calls it with upstream's
161
+ // own `{ hash, css, name, filename }` object and reads the string back.
162
+ const result = await binding.compileWithCssHash(source, resolved, options.cssHash);
191
163
  return applyWarningFilter(result, warningFilter);
192
164
  }
193
165
  if (resolved?.modernAst) {
@@ -254,6 +226,11 @@ module.exports.compileModuleBuffers = binding.compileModuleBuffers;
254
226
  module.exports.compileBatch = compileBatch;
255
227
  module.exports.compileBatchRaw = binding.compileBatch;
256
228
  module.exports.compileAsync = compileAsync;
229
+ // The only entry that honours a function-valued `cssHash`. The callback takes
230
+ // upstream's single `{ hash, css, name, filename }` argument and returns the
231
+ // scope class; the synchronous entries reject a function `cssHash` rather than
232
+ // dropping it. Returns a plain CompileResult (no envelope).
233
+ module.exports.compileWithCssHash = binding.compileWithCssHash;
257
234
  module.exports.compileBatchAsync = compileBatchAsync;
258
235
  module.exports.compileEnvelopeAsync = binding.compileEnvelopeAsync;
259
236
  module.exports.compileBatchAsyncRaw = binding.compileBatchAsync;
@@ -277,4 +254,4 @@ module.exports.decodeParseEnvelope = decodeParseEnvelope;
277
254
  // with `submodules/svelte/packages/svelte/package.json` by hand; run
278
255
  // `node scripts/dev/check-vps-version.mjs` (also wired into CI) to
279
256
  // catch drift.
280
- module.exports.VERSION = '5.56.9';
257
+ module.exports.VERSION = '5.56.10';
package/index.d.ts CHANGED
@@ -46,7 +46,8 @@ export interface CompileOptions {
46
46
  * Custom hash function for CSS scoping. Called once per component with the
47
47
  * component's CSS; the returned string becomes the scope class. Because it
48
48
  * depends on the CSS, it is bridged into the compiler through a threadsafe
49
- * callback and is only supported on the async path — use `compileAsync`.
49
+ * callback and is only supported on the async path — use `compileAsync`
50
+ * (or `compileWithCssHash`, which it routes to).
50
51
  * The synchronous `compile` throws if given a `cssHash` function; pass a
51
52
  * pre-computed constant via `cssHashOverride` instead.
52
53
  */
@@ -192,6 +193,13 @@ export function compileModule(
192
193
  * {@link decodeEnvelope} to obtain
193
194
  * the legacy {@link CompileResult} shape; or pass the buffer through
194
195
  * worker `postMessage` (transferable) to avoid a copy.
196
+ *
197
+ * Unlike {@link compile}, this does NOT go through the wrapper that resolves
198
+ * upstream's function-valued options, so a `runes` / `css` / `customElement` /
199
+ * `warningFilter` callback is **rejected** here rather than honoured — evaluate
200
+ * it yourself and pass the plain value. `runes` and `warningFilter` used to be
201
+ * dropped in silence instead, which produced a successful compile with the
202
+ * wrong result; `css` and `customElement` already threw.
195
203
  */
196
204
  export function compileEnvelope(source: string, options?: CompileOptions): Buffer;
197
205
  export function compileModuleEnvelope(
@@ -275,6 +283,19 @@ export function compileAsync(
275
283
  options?: CompileOptions,
276
284
  ): Promise<CompileResult>;
277
285
 
286
+ /**
287
+ * The one entry that honours a function-valued `cssHash`. The callback receives
288
+ * upstream's single `{ hash, css, name, filename }` argument and returns the
289
+ * scope class; a throw aborts the compile. `compileAsync` routes here
290
+ * automatically when `options.cssHash` is a function, so most callers never need
291
+ * this directly.
292
+ */
293
+ export function compileWithCssHash(
294
+ source: string,
295
+ options: CompileOptions | undefined | null,
296
+ cssHash: NonNullable<CompileOptions['cssHash']>,
297
+ ): Promise<CompileResult>;
298
+
278
299
  /** Async variant of {@link compileBatch}. */
279
300
  export function compileBatchAsync(
280
301
  inputs: CompileBatchInput[],
@@ -314,6 +335,13 @@ export function compileModuleBuffers(
314
335
  /**
315
336
  * The legacy JSON-on-the-boundary path. Kept exported for parity tests
316
337
  * and as an escape hatch — production callers should use {@link compile}.
338
+ *
339
+ * Unlike {@link compile}, this does NOT go through the wrapper that resolves
340
+ * upstream's function-valued options, so a `runes` / `css` / `customElement` /
341
+ * `warningFilter` callback is **rejected** here rather than honoured — evaluate
342
+ * it yourself and pass the plain value. `runes` and `warningFilter` used to be
343
+ * dropped in silence instead, which produced a successful compile with the
344
+ * wrong result; `css` and `customElement` already threw.
317
345
  */
318
346
  export function compileLegacy(source: string, options?: CompileOptions): CompileResult;
319
347
  export function compileModuleLegacy(
@@ -345,12 +373,29 @@ export interface ParseOptions {
345
373
  * JSON-parse step.
346
374
  */
347
375
  skipCssAst?: boolean;
376
+ /**
377
+ * `modern` from `svelte/compiler`'s `parse()`. **Defaults to `false`**,
378
+ * which returns the LEGACY AST (`{ html, instance, module, css }`); pass
379
+ * `true` for the modern `Root` shape. The modern AST stays opt-in until
380
+ * Svelte 6, and this binding defaults the same way official does.
381
+ */
382
+ modern?: boolean;
383
+ /**
384
+ * `loose` from `svelte/compiler`'s `parse()`. Recover from a parse error
385
+ * and return an AST anyway — what an editor integration needs to parse a
386
+ * document mid-keystroke. Not blanket recovery: a source official still
387
+ * rejects under `loose` (e.g. a stray `</div>`) throws here too.
388
+ */
389
+ loose?: boolean;
348
390
  }
349
391
 
350
392
  /**
351
393
  * Parse a Svelte component and return the AST as a JSON string. The
352
394
  * caller is responsible for `JSON.parse` on the returned value.
353
395
  *
396
+ * Without `{ modern: true }` this returns the LEGACY AST, matching
397
+ * `svelte/compiler`'s default.
398
+ *
354
399
  * For the fastest path skip JSON entirely: use {@link parseEnvelope}
355
400
  * with `decodeParseEnvelope` from
356
401
  * `@rsvelte/vite-plugin-svelte-native/parse-envelope.js`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsvelte/vite-plugin-svelte-native",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "description": "NAPI bindings to the rsvelte compiler — used by the @rsvelte vite-plugin-svelte shim",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -30,11 +30,11 @@
30
30
  "index.d.ts"
31
31
  ],
32
32
  "optionalDependencies": {
33
- "@rsvelte/vite-plugin-svelte-native-darwin-arm64": "^0.3.7",
34
- "@rsvelte/vite-plugin-svelte-native-darwin-x64": "^0.3.7",
35
- "@rsvelte/vite-plugin-svelte-native-linux-arm64-gnu": "^0.3.7",
36
- "@rsvelte/vite-plugin-svelte-native-linux-x64-gnu": "^0.3.7",
37
- "@rsvelte/vite-plugin-svelte-native-win32-x64-msvc": "^0.3.7"
33
+ "@rsvelte/vite-plugin-svelte-native-darwin-arm64": "^0.3.9",
34
+ "@rsvelte/vite-plugin-svelte-native-darwin-x64": "^0.3.9",
35
+ "@rsvelte/vite-plugin-svelte-native-linux-arm64-gnu": "^0.3.9",
36
+ "@rsvelte/vite-plugin-svelte-native-linux-x64-gnu": "^0.3.9",
37
+ "@rsvelte/vite-plugin-svelte-native-win32-x64-msvc": "^0.3.9"
38
38
  },
39
39
  "publishConfig": {
40
40
  "access": "public"
package/parse-envelope.js CHANGED
@@ -19,7 +19,7 @@ const MAGIC = 0x3156_5052; // "RPV1" little-endian
19
19
  // reorder, `typeParameters` on function-like nodes, Identifier `optional`);
20
20
  // v4 adds the object-method `typeParameters`-after-`body` flag byte.
21
21
  // Keep in lockstep with `napi_raw_parse.rs`'s `VERSION`.
22
- const VERSION = 4;
22
+ const VERSION = 5;
23
23
  const HEADER_LEN = 24;
24
24
 
25
25
  // Tags — must mirror napi_raw_parse.rs.
@@ -173,6 +173,7 @@ const LV_NUMBER_I64 = 3;
173
173
  const LV_NUMBER_F64 = 4;
174
174
  const LV_STRING = 5;
175
175
  const LV_REGEX = 6;
176
+ const LV_BIGINT = 7;
176
177
 
177
178
  // Element tag -> serialised `type` string. The decoder uses this
178
179
  // table for the shared element shape (RegularElement, Component, …).
@@ -660,6 +661,10 @@ function readLiteralValue(ctx) {
660
661
  return readStr(ctx);
661
662
  case LV_REGEX:
662
663
  return {}; // Literal.regex value is serialised as an empty object upstream.
664
+ case LV_BIGINT:
665
+ // Sentinel consumed by readJsLiteral (value becomes a BigInt and the
666
+ // digits land on the node's `bigint` property, acorn-style).
667
+ return { bigint: readStr(ctx) };
663
668
  default:
664
669
  throw new EnvelopeError(`parse envelope: bad LiteralValue tag 0x${tag.toString(16)}`);
665
670
  }
@@ -728,6 +733,13 @@ function readJsLiteral(ctx, start, end) {
728
733
  const regex = readRegex(ctx);
729
734
  const node = { type: 'Literal', start, end };
730
735
  if (loc !== null) node.loc = loc;
736
+ if (value !== null && typeof value === 'object' && typeof value.bigint === 'string') {
737
+ node.value = BigInt(value.bigint);
738
+ node.raw = raw;
739
+ node.bigint = value.bigint;
740
+ if (regex !== null) node.regex = regex;
741
+ return node;
742
+ }
731
743
  node.value = value;
732
744
  node.raw = raw;
733
745
  if (regex !== null) node.regex = regex;
@@ -1640,7 +1652,14 @@ function readJsComment(ctx, start, end) {
1640
1652
  const kindByte = readU8(ctx);
1641
1653
  const kind = kindByte === 1 ? 'Block' : 'Line';
1642
1654
  const value = readStr(ctx);
1655
+ // Only an in-tag comment's `loc` carries `character`; a script comment's
1656
+ // comes from the JS parser, which does not produce one.
1657
+ const hasCharacter = readU8(ctx) === 1;
1643
1658
  const loc = readSourceLocation(ctx);
1659
+ if (!hasCharacter) {
1660
+ delete loc.start.character;
1661
+ delete loc.end.character;
1662
+ }
1644
1663
  return { type: kind, start, end, value, loc };
1645
1664
  }
1646
1665