@gjsify/rolldown-plugin-gjsify 0.4.28 → 0.4.29

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.
@@ -29,8 +29,8 @@ export const setupForBrowser = async (input) => {
29
29
  };
30
30
  const aliasMap = {
31
31
  ...browserPolyfillAliases,
32
- ...(input.pluginOptions.aliases ?? {}),
33
- ...(input.userAliases ?? {}),
32
+ ...input.pluginOptions.aliases,
33
+ ...input.userAliases,
34
34
  };
35
35
  const options = {
36
36
  input: entryPoints,
package/lib/app/gjs.js CHANGED
@@ -15,7 +15,7 @@ import { deepkitPlugin } from '@gjsify/rolldown-plugin-deepkit';
15
15
  import blueprintPlugin from '@gjsify/vite-plugin-blueprint';
16
16
  import { getAliasesForGjs } from '../utils/alias.js';
17
17
  import { globToEntryPoints } from '../utils/entry-points.js';
18
- import { nodeModulesPathRewritePlugin, getBundleDirFromOutput, } from '../plugins/rewrite-node-modules-paths.js';
18
+ import { nodeModulesPathRewritePlugin, getBundleDirFromOutput } from '../plugins/rewrite-node-modules-paths.js';
19
19
  import { processStubPlugin } from '../plugins/process-stub.js';
20
20
  import { cssAsStringPlugin } from '../plugins/css-as-string.js';
21
21
  import { shebangPlugin, resolveShebangLine, inputShebangStripPlugin } from '../plugins/shebang.js';
@@ -77,8 +77,8 @@ export const setupForGjs = async (input) => {
77
77
  const aliasMap = {
78
78
  ...getAliasesForGjs({ external }),
79
79
  'unicorn-magic': unicornMagicShim,
80
- ...(input.pluginOptions.aliases ?? {}),
81
- ...(input.userAliases ?? {}),
80
+ ...input.pluginOptions.aliases,
81
+ ...input.userAliases,
82
82
  };
83
83
  // The console shim replaces all `console` references with print()/printerr()-
84
84
  // based implementations that bypass GLib.log_structured() — no prefix,
@@ -91,9 +91,7 @@ export const setupForGjs = async (input) => {
91
91
  // resolution lands at a non-existent location. Walk up via
92
92
  // createRequire's node_modules-aware resolver as a fallback.
93
93
  const consoleShimEnabled = input.pluginOptions.consoleShim !== false;
94
- const consoleShimPath = consoleShimEnabled
95
- ? resolveConsoleShim()
96
- : null;
94
+ const consoleShimPath = consoleShimEnabled ? resolveConsoleShim() : null;
97
95
  // The auto-globals inject stub (when present) is side-effect-imported
98
96
  // via a virtual entry — its register modules write to globalThis, so
99
97
  // the import chain matters but no name binding does. We can't use
@@ -239,9 +237,7 @@ function wrapInputWithSideEffects(input, sideEffects) {
239
237
  }
240
238
  wrappedInput = out;
241
239
  }
242
- const sideEffectImports = sideEffects
243
- .map((p) => `import ${JSON.stringify(p)};`)
244
- .join('\n');
240
+ const sideEffectImports = sideEffects.map((p) => `import ${JSON.stringify(p)};`).join('\n');
245
241
  // Resolved real-path targets from `userEntries` get their
246
242
  // moduleSideEffects forced to 'no-treeshake' so the user-entry's
247
243
  // top-level body (`run({...})`, side-effect calls) survives tree-shake
@@ -249,7 +245,7 @@ function wrapInputWithSideEffects(input, sideEffects) {
249
245
  const resolvedTargets = new Set();
250
246
  const plugin = {
251
247
  name: 'gjsify-virtual-entry',
252
- async resolveId(source, importer) {
248
+ async resolveId(source, _importer) {
253
249
  if (source.startsWith(PREFIX))
254
250
  return source;
255
251
  // Force-mark the resolved user-entry target as having
package/lib/app/node.js CHANGED
@@ -9,7 +9,7 @@ import { deepkitPlugin } from '@gjsify/rolldown-plugin-deepkit';
9
9
  import { EXTERNALS_NODE } from '@gjsify/resolve-npm';
10
10
  import { getAliasesForNode } from '../utils/alias.js';
11
11
  import { globToEntryPoints } from '../utils/entry-points.js';
12
- import { nodeModulesPathRewritePlugin, getBundleDirFromOutput, } from '../plugins/rewrite-node-modules-paths.js';
12
+ import { nodeModulesPathRewritePlugin, getBundleDirFromOutput } from '../plugins/rewrite-node-modules-paths.js';
13
13
  import { cssAsStringPlugin } from '../plugins/css-as-string.js';
14
14
  export const setupForNode = async (input) => {
15
15
  const userExternal = input.userExternal ?? [];
@@ -21,11 +21,7 @@ export const setupForNode = async (input) => {
21
21
  // way esbuild's did (`gi://*`, `@girs/*`). We use a function predicate
22
22
  // instead so the gi:// URI scheme and the @girs/ namespace are matched
23
23
  // by prefix.
24
- const exactExternal = [
25
- ...EXTERNALS_NODE,
26
- 'node-datachannel',
27
- ...userExternal,
28
- ];
24
+ const exactExternal = [...EXTERNALS_NODE, 'node-datachannel', ...userExternal];
29
25
  const external = (id) => {
30
26
  if (id.startsWith('gi://'))
31
27
  return true;
@@ -40,8 +36,8 @@ export const setupForNode = async (input) => {
40
36
  const entryPoints = await globToEntryPoints(input.input, exclude);
41
37
  const aliasMap = {
42
38
  ...getAliasesForNode({ external }),
43
- ...(input.pluginOptions.aliases ?? {}),
44
- ...(input.userAliases ?? {}),
39
+ ...input.pluginOptions.aliases,
40
+ ...input.userAliases,
45
41
  };
46
42
  const bundleDir = getBundleDirFromOutput(input.output);
47
43
  // Rolldown's CJS interop wraps bundled CJS via `__commonJSMin` and
package/lib/index.d.ts CHANGED
@@ -3,12 +3,12 @@ export * from './utils/index.js';
3
3
  export * from './app/index.js';
4
4
  export * from './library/index.js';
5
5
  export { REWRITE_FILTER, getBundleDirFromOutput, rewriteContents, shouldRewrite, nodeModulesPathRewritePlugin, } from './plugins/rewrite-node-modules-paths.js';
6
- export type { NodeModulesPathRewriteOptions, RewriteResult, } from './plugins/rewrite-node-modules-paths.js';
6
+ export type { NodeModulesPathRewriteOptions, RewriteResult } from './plugins/rewrite-node-modules-paths.js';
7
7
  export { processStubPlugin, GJS_PROCESS_STUB, composeBanner } from './plugins/process-stub.js';
8
8
  export type { ProcessStubPluginOptions } from './plugins/process-stub.js';
9
9
  export { cssAsStringPlugin } from './plugins/css-as-string.js';
10
10
  export { textLoaderPlugin } from './plugins/text-loader.js';
11
- export type { TextLoaderPluginOptions } from './plugins/text-loader.js';
11
+ export type { TextLoaderPluginOptions, LoaderKind } from './plugins/text-loader.js';
12
12
  export { shebangPlugin, GJS_SHEBANG, NODE_SHEBANG, expandEnvTemplate, resolveShebangLine } from './plugins/shebang.js';
13
13
  export type { ShebangPluginOptions } from './plugins/shebang.js';
14
14
  export { gjsImportsEmptyPlugin } from './plugins/gjs-imports-empty.js';
@@ -27,8 +27,8 @@ export const setupLib = async (input) => {
27
27
  // which doesn't match the package.json `exports` map.
28
28
  const preserveModulesRoot = computeCommonRoot(entryPoints);
29
29
  const aliasMap = {
30
- ...(input.pluginOptions.aliases ?? {}),
31
- ...(input.userAliases ?? {}),
30
+ ...input.pluginOptions.aliases,
31
+ ...input.userAliases,
32
32
  };
33
33
  // Library mode keeps all third-party / workspace imports as-is so the
34
34
  // emitted package re-exports its dep tree by reference. Rolldown's
@@ -22,7 +22,6 @@
22
22
  // constructor — breaking `util.inherits(Child, Stream)` patterns.
23
23
  export function aliasPlugin(options) {
24
24
  const entries = options.entries;
25
- const keys = Object.keys(entries);
26
25
  return {
27
26
  name: 'gjsify-alias',
28
27
  resolveId: {
@@ -1,4 +1,5 @@
1
1
  import type { Plugin } from 'rolldown';
2
+ import type { Targets } from 'lightningcss';
2
3
  export interface CssAsStringOptions {
3
4
  /**
4
5
  * lightningcss browser targets passed to `bundleAsync`. When set,
@@ -7,7 +8,7 @@ export interface CssAsStringOptions {
7
8
  * match the GTK4 CSS parser. Omit or leave undefined to skip
8
9
  * lowering (output stays as-authored except for `@import` inlining).
9
10
  */
10
- targets?: import('lightningcss').Targets;
11
+ targets?: Targets;
11
12
  /**
12
13
  * When true (default), `@import` statements are resolved by
13
14
  * lightningcss `bundleAsync`. Set false to fall back to a plain
@@ -41,7 +41,8 @@ import { dirname, isAbsolute, resolve as resolvePath } from 'node:path';
41
41
  import { pathToFileURL } from 'node:url';
42
42
  let _bundlerPromise = null;
43
43
  async function pickBundler() {
44
- const forced = globalThis.process?.env?.GJSIFY_CSS_BACKEND;
44
+ const forced = globalThis.process?.env
45
+ ?.GJSIFY_CSS_BACKEND;
45
46
  if (forced === 'npm')
46
47
  return loadNpmBundler();
47
48
  if (forced === 'native') {
@@ -1,10 +1,13 @@
1
1
  import type { Plugin } from 'rolldown';
2
+ /** Loader kind values accepted under `gjsify.loaders`. */
3
+ export type LoaderKind = 'text' | 'dataurl';
2
4
  export interface TextLoaderPluginOptions {
3
5
  /**
4
- * Map of file extension (with leading `.`) → loader kind. Currently only
5
- * `'text'` is implemented; the field is shaped this way to leave room
6
- * for `'json'` / `'binary'` later without a config break.
6
+ * Map of file extension (with leading `.`) → loader kind.
7
+ * `'text'` file contents as JS string default export.
8
+ * `'dataurl'` `data:<mime>;base64,<b64>` string default export.
9
+ * MIME inferred from extension (.png → image/png etc.).
7
10
  */
8
- loaders?: Record<string, 'text'>;
11
+ loaders?: Record<string, LoaderKind>;
9
12
  }
10
13
  export declare function textLoaderPlugin(options?: TextLoaderPluginOptions): Plugin | null;
@@ -1,24 +1,56 @@
1
- // Generic "load file as JS string default export" plugin.
1
+ // Generic "load file as JS string / data-URL default export" plugin.
2
2
  //
3
3
  // Mirrors `css-as-string` but lets the user opt-in arbitrary extensions
4
- // through `bundler.loaders` config, e.g.:
4
+ // through `gjsify.loaders` config, e.g.:
5
5
  //
6
- // "bundler": { "loaders": { ".ui": "text", ".asm": "text" } }
6
+ // "loaders": { ".ui": "text", ".asm": "text", ".glsl": "text", ".png": "dataurl" }
7
7
  //
8
- // — replaces the esbuild `loader: { '.ui': 'text' }` shorthand from the
9
- // pre-Rolldown era. Rolldown does not classify unknown extensions as text
8
+ // — replaces the esbuild `loader: { '.ui': 'text', '.png': 'dataurl' }` shorthand
9
+ // from the pre-Rolldown era. Rolldown does not classify unknown extensions as text
10
10
  // by default; without a hook it tries to parse them as JS and fails.
11
+ //
12
+ // Loader kinds:
13
+ // 'text' — file contents as a JS string default export
14
+ // (`export default "…source…"`)
15
+ // 'dataurl' — file encoded as a data: URL string default export
16
+ // (`export default "data:<mime>;base64,<b64>"`)
17
+ // MIME is inferred from the file extension; falls back to
18
+ // `application/octet-stream` for unknown extensions.
19
+ // Useful for Excalibur's `ImageSource` constructor and similar
20
+ // libraries that want a data: URL rather than a separate asset.
11
21
  import { readFile } from 'node:fs/promises';
22
+ /** MIME type lookup for common binary / shader formats. */
23
+ const MIME_BY_EXT = {
24
+ '.png': 'image/png',
25
+ '.jpg': 'image/jpeg',
26
+ '.jpeg': 'image/jpeg',
27
+ '.gif': 'image/gif',
28
+ '.webp': 'image/webp',
29
+ '.svg': 'image/svg+xml',
30
+ '.ico': 'image/x-icon',
31
+ '.avif': 'image/avif',
32
+ '.bmp': 'image/bmp',
33
+ '.tiff': 'image/tiff',
34
+ '.tif': 'image/tiff',
35
+ '.wasm': 'application/wasm',
36
+ };
37
+ function mimeForExtension(ext) {
38
+ return MIME_BY_EXT[ext.toLowerCase()] ?? 'application/octet-stream';
39
+ }
12
40
  export function textLoaderPlugin(options = {}) {
13
- const exts = Object.entries(options.loaders ?? {})
14
- .filter(([, kind]) => kind === 'text')
15
- .map(([ext]) => ext);
16
- if (exts.length === 0)
41
+ const loaders = options.loaders ?? {};
42
+ const entries = Object.entries(loaders);
43
+ const textExts = entries.filter(([, kind]) => kind === 'text').map(([ext]) => ext);
44
+ const dataurlExts = entries.filter(([, kind]) => kind === 'dataurl').map(([ext]) => ext);
45
+ const allExts = [...textExts, ...dataurlExts];
46
+ if (allExts.length === 0)
17
47
  return null;
18
48
  // Build a single regex matching any of the configured extensions:
19
- // ['.ui', '.asm'] → /\.(ui|asm)$/
20
- const escaped = exts.map((e) => e.replace(/^\./, '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
49
+ // ['.ui', '.asm', '.png'] → /\.(ui|asm|png)$/
50
+ const escaped = allExts.map((e) => e.replace(/^\./, '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
21
51
  const filter = new RegExp(`\\.(?:${escaped.join('|')})$`);
52
+ // Index extensions → kind for fast lookup in the load hook.
53
+ const kindMap = new Map(entries.map(([ext, kind]) => [ext.toLowerCase(), kind]));
22
54
  // Use the function-form `load(id)` (Rollup-compatible) rather than the
23
55
  // newer `load: { filter, handler }` shape. The newer shape was observed
24
56
  // not to claim unknown-extension files reliably under Rolldown rc.18 —
@@ -27,10 +59,24 @@ export function textLoaderPlugin(options = {}) {
27
59
  // as `@gjsify/vite-plugin-blueprint`'s `.blp` hook) intercepts during
28
60
  // module-load lookup and works under both Vite and Rolldown.
29
61
  return {
30
- name: 'gjsify-text-loader',
62
+ name: 'gjsify-asset-loader',
31
63
  async load(id) {
32
64
  if (!filter.test(id))
33
65
  return null;
66
+ // Determine the extension (lowercase, with leading dot).
67
+ const dotIdx = id.lastIndexOf('.');
68
+ const ext = dotIdx >= 0 ? id.slice(dotIdx).toLowerCase() : '';
69
+ const kind = kindMap.get(ext) ?? 'text';
70
+ if (kind === 'dataurl') {
71
+ const bytes = await readFile(id);
72
+ const mime = mimeForExtension(ext);
73
+ const b64 = bytes.toString('base64');
74
+ return {
75
+ code: `export default ${JSON.stringify(`data:${mime};base64,${b64}`)};`,
76
+ moduleType: 'js',
77
+ };
78
+ }
79
+ // kind === 'text'
34
80
  const code = await readFile(id, 'utf8');
35
81
  return {
36
82
  code: `export default ${JSON.stringify(code)};`,
@@ -15,10 +15,34 @@
15
15
  // `globalThis.console` untouched and routing user `console.log(…)` calls
16
16
  // through our object.
17
17
  // @ts-ignore — resolved by Rolldown at user-build time, not by tsc here.
18
- import { log, info, debug, warn, error, dir, dirxml, table, time, timeEnd, timeLog, trace, assert, clear, count, countReset, group, groupCollapsed, groupEnd, profile, profileEnd, timeStamp } from '@gjsify/console';
18
+ import * as gjsConsole from '@gjsify/console';
19
+ // NOTE: a namespace import is used deliberately. It is a single statement that
20
+ // no formatter (oxfmt) can wrap across lines, so the `@ts-ignore` above always
21
+ // sits on the line immediately preceding the import and reliably suppresses the
22
+ // TS2307 (`@gjsify/console` is resolved by Rolldown at user-build time, not by
23
+ // tsc here). A multi-line named import would let the reformatter detach the
24
+ // suppression from the offending `from '@gjsify/console'` line.
19
25
  export const console = {
20
- log, info, debug, warn, error, dir, dirxml, table,
21
- time, timeEnd, timeLog, trace, assert, clear,
22
- count, countReset, group, groupCollapsed, groupEnd,
23
- profile, profileEnd, timeStamp,
26
+ log: gjsConsole.log,
27
+ info: gjsConsole.info,
28
+ debug: gjsConsole.debug,
29
+ warn: gjsConsole.warn,
30
+ error: gjsConsole.error,
31
+ dir: gjsConsole.dir,
32
+ dirxml: gjsConsole.dirxml,
33
+ table: gjsConsole.table,
34
+ time: gjsConsole.time,
35
+ timeEnd: gjsConsole.timeEnd,
36
+ timeLog: gjsConsole.timeLog,
37
+ trace: gjsConsole.trace,
38
+ assert: gjsConsole.assert,
39
+ clear: gjsConsole.clear,
40
+ count: gjsConsole.count,
41
+ countReset: gjsConsole.countReset,
42
+ group: gjsConsole.group,
43
+ groupCollapsed: gjsConsole.groupCollapsed,
44
+ groupEnd: gjsConsole.groupEnd,
45
+ profile: gjsConsole.profile,
46
+ profileEnd: gjsConsole.profileEnd,
47
+ timeStamp: gjsConsole.timeStamp,
24
48
  };
@@ -1,4 +1,4 @@
1
- import { EXTERNALS_NODE, EXTERNALS_NPM, ALIASES_GENERAL_FOR_GJS, ALIASES_NODE_FOR_GJS, ALIASES_WEB_FOR_GJS, ALIASES_GENERAL_FOR_NODE, ALIASES_GJS_FOR_NODE, ALIASES_WEB_FOR_NODE } from "@gjsify/resolve-npm";
1
+ import { EXTERNALS_NODE, EXTERNALS_NPM, ALIASES_GENERAL_FOR_GJS, ALIASES_NODE_FOR_GJS, ALIASES_WEB_FOR_GJS, ALIASES_GENERAL_FOR_NODE, ALIASES_GJS_FOR_NODE, ALIASES_WEB_FOR_NODE, } from '@gjsify/resolve-npm';
2
2
  export const setNodeAliasPrefix = (ALIASES) => {
3
3
  // Also resolve alias names with `node:${ALIAS}`
4
4
  for (const ALIAS in ALIASES) {
@@ -11,12 +11,12 @@ export const setNodeAliasPrefix = (ALIASES) => {
11
11
  }
12
12
  return ALIASES;
13
13
  };
14
- const getAliasesGeneralForGjs = (options) => ALIASES_GENERAL_FOR_GJS;
15
- const getAliasesNodeForGjs = (options) => setNodeAliasPrefix(ALIASES_NODE_FOR_GJS);
16
- const getAliasesWebForGjs = (options) => ALIASES_WEB_FOR_GJS;
17
- const getAliasesGeneralForNode = (options) => ALIASES_GENERAL_FOR_NODE;
18
- const getAliasesGjsForNode = (options) => ALIASES_GJS_FOR_NODE;
19
- const getAliasesWebForNode = (options) => ALIASES_WEB_FOR_NODE;
14
+ const getAliasesGeneralForGjs = (_options) => ALIASES_GENERAL_FOR_GJS;
15
+ const getAliasesNodeForGjs = (_options) => setNodeAliasPrefix(ALIASES_NODE_FOR_GJS);
16
+ const getAliasesWebForGjs = (_options) => ALIASES_WEB_FOR_GJS;
17
+ const getAliasesGeneralForNode = (_options) => ALIASES_GENERAL_FOR_NODE;
18
+ const getAliasesGjsForNode = (_options) => ALIASES_GJS_FOR_NODE;
19
+ const getAliasesWebForNode = (_options) => ALIASES_WEB_FOR_NODE;
20
20
  export const getAliasesForGjs = (options) => {
21
21
  return { ...getAliasesGeneralForGjs(options), ...getAliasesNodeForGjs(options), ...getAliasesWebForGjs(options) };
22
22
  };
@@ -24,6 +24,6 @@ export const getAliasesForNode = (options) => {
24
24
  return { ...getAliasesGeneralForNode(options), ...getAliasesGjsForNode(options), ...getAliasesWebForNode(options) };
25
25
  };
26
26
  /** Array of Node.js build in module names (also with node: prefix) */
27
- export const externalNode = [...EXTERNALS_NODE, ...EXTERNALS_NODE.map(E => `node:${E}`)];
27
+ export const externalNode = [...EXTERNALS_NODE, ...EXTERNALS_NODE.map((E) => `node:${E}`)];
28
28
  /** Array of NPM module names for which we have our own implementation */
29
29
  export const externalNPM = [...EXTERNALS_NPM];
@@ -58,7 +58,7 @@ async function applyExcludeGlobals(detected, currentInject, extraRegisterPaths,
58
58
  const filtered = detectedToRegisterPaths(detected);
59
59
  for (const p of extraRegisterPaths)
60
60
  filtered.add(p);
61
- const injectPath = filtered.size > 0 ? (await writeRegisterInjectFile(filtered)) ?? undefined : undefined;
61
+ const injectPath = filtered.size > 0 ? ((await writeRegisterInjectFile(filtered)) ?? undefined) : undefined;
62
62
  return { detected, injectPath };
63
63
  }
64
64
  function detectedToRegisterPaths(detected) {
@@ -150,9 +150,7 @@ export async function detectAutoGlobals(analysisOptions, pluginOptions, gjsifyPl
150
150
  // shape: caller plugins first (PnP, user text-loaders), then the
151
151
  // gjsify chain (which may be either a single RolldownPluginOption
152
152
  // or an array of them depending on the factory shape).
153
- const gjsifyPluginsArray = Array.isArray(gjsifyInstance)
154
- ? gjsifyInstance
155
- : [gjsifyInstance];
153
+ const gjsifyPluginsArray = Array.isArray(gjsifyInstance) ? gjsifyInstance : [gjsifyInstance];
156
154
  const chunkCodes = await bundler({
157
155
  rolldownInput: {
158
156
  input: inputWithInject,
@@ -181,7 +179,8 @@ export async function detectAutoGlobals(analysisOptions, pluginOptions, gjsifyPl
181
179
  newDetected.add(id);
182
180
  }
183
181
  catch (e) {
184
- if (globalThis.process?.env?.GJSIFY_DEBUG_AUTO_GLOBALS) {
182
+ if (globalThis.process?.env
183
+ ?.GJSIFY_DEBUG_AUTO_GLOBALS) {
185
184
  const path = `/tmp/gjsify-auto-globals-failed-chunk-${i}.mjs`;
186
185
  try {
187
186
  // eslint-disable-next-line @typescript-eslint/no-require-imports
@@ -189,7 +188,9 @@ export async function detectAutoGlobals(analysisOptions, pluginOptions, gjsifyPl
189
188
  fs.writeFileSync(path, code);
190
189
  console.error(`[gjsify-auto-globals] parse failed on chunk #${i} — wrote ${path} for inspection`);
191
190
  }
192
- catch { /* ignore */ }
191
+ catch {
192
+ /* ignore */
193
+ }
193
194
  }
194
195
  throw e;
195
196
  }
@@ -113,11 +113,7 @@ function extractBindingNames(node) {
113
113
  ? extractBindingNames(p.argument)
114
114
  : extractBindingNames(p.value));
115
115
  case 'ArrayPattern':
116
- return node.elements.flatMap((e) => e
117
- ? e.type === 'RestElement'
118
- ? extractBindingNames(e.argument)
119
- : extractBindingNames(e)
120
- : []);
116
+ return node.elements.flatMap((e) => e ? (e.type === 'RestElement' ? extractBindingNames(e.argument) : extractBindingNames(e)) : []);
121
117
  case 'AssignmentPattern':
122
118
  return extractBindingNames(node.left);
123
119
  case 'RestElement':
@@ -1,5 +1,12 @@
1
1
  export const getJsExtensions = (allowExt) => {
2
- const extensions = { '.js': '.js', '.ts': '.js', '.mts': '.js', '.cts': '.js', '.cjs': '.js', '.mjs': '.js' };
2
+ const extensions = {
3
+ '.js': '.js',
4
+ '.ts': '.js',
5
+ '.mts': '.js',
6
+ '.cts': '.js',
7
+ '.cjs': '.js',
8
+ '.mjs': '.js',
9
+ };
3
10
  if (allowExt && extensions[allowExt]) {
4
11
  delete extensions[allowExt];
5
12
  }
@@ -53,9 +53,7 @@ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
53
53
  * `readdirSync` / `existsSync` skip the AST parse entirely (cheap fast path).
54
54
  */
55
55
  export function inlineStaticReads(src, sourceFilePath) {
56
- if (!src.includes('readFileSync') &&
57
- !src.includes('readdirSync') &&
58
- !src.includes('existsSync')) {
56
+ if (!src.includes('readFileSync') && !src.includes('readdirSync') && !src.includes('existsSync')) {
59
57
  return { contents: src, inlined: 0 };
60
58
  }
61
59
  let ast;
@@ -112,7 +110,7 @@ export function inlineStaticReads(src, sourceFilePath) {
112
110
  * `undefined` if the call doesn't match an inlinable pattern or the path
113
111
  * couldn't be resolved or the file doesn't exist.
114
112
  */
115
- function tryInlineCall(node, ctx, src) {
113
+ function tryInlineCall(node, ctx, _src) {
116
114
  const callee = node.callee;
117
115
  // `JSON.parse(readFileSync(<path>, "utf8"))` — collapse the whole
118
116
  // composition. Recognising it specifically lets us emit a parsed-JSON
@@ -120,8 +118,10 @@ function tryInlineCall(node, ctx, src) {
120
118
  // which esbuild can dead-code-eliminate against.
121
119
  if (callee.type === 'MemberExpression' &&
122
120
  !callee.computed &&
123
- callee.object.type === 'Identifier' && callee.object.name === 'JSON' &&
124
- callee.property.type === 'Identifier' && callee.property.name === 'parse' &&
121
+ callee.object.type === 'Identifier' &&
122
+ callee.object.name === 'JSON' &&
123
+ callee.property.type === 'Identifier' &&
124
+ callee.property.name === 'parse' &&
125
125
  node.arguments.length >= 1 &&
126
126
  node.arguments[0].type === 'CallExpression') {
127
127
  const inner = node.arguments[0];
@@ -377,7 +377,7 @@ function evalExpr(node, ctx) {
377
377
  }
378
378
  }
379
379
  const base = evalExpr(ne.arguments[1], ctx);
380
- const baseStr = base instanceof URL ? base.href : (typeof base === 'string' ? base : undefined);
380
+ const baseStr = base instanceof URL ? base.href : typeof base === 'string' ? base : undefined;
381
381
  if (!baseStr)
382
382
  return undefined;
383
383
  try {
@@ -394,7 +394,7 @@ function evalExpr(node, ctx) {
394
394
  const name = identifierName(ce.callee);
395
395
  if (name === 'fileURLToPath') {
396
396
  const arg = evalExpr(ce.arguments[0], ctx);
397
- const url = arg instanceof URL ? arg.href : (typeof arg === 'string' ? arg : undefined);
397
+ const url = arg instanceof URL ? arg.href : typeof arg === 'string' ? arg : undefined;
398
398
  if (!url)
399
399
  return undefined;
400
400
  try {
@@ -471,7 +471,9 @@ function evalEncodingExpr(node) {
471
471
  continue;
472
472
  const key = p.key.type === 'Identifier'
473
473
  ? p.key.name
474
- : p.key.type === 'Literal' ? String(p.key.value) : undefined;
474
+ : p.key.type === 'Literal'
475
+ ? String(p.key.value)
476
+ : undefined;
475
477
  if (key !== 'encoding')
476
478
  continue;
477
479
  if (p.value.type === 'Literal' && typeof p.value.value === 'string') {
@@ -19,5 +19,8 @@ export function merge(target, ...sources) {
19
19
  return target;
20
20
  }
21
21
  function isPlainObject(val) {
22
- return typeof val === 'object' && val !== null && !Array.isArray(val) && Object.getPrototypeOf(val) === Object.prototype;
22
+ return (typeof val === 'object' &&
23
+ val !== null &&
24
+ !Array.isArray(val) &&
25
+ Object.getPrototypeOf(val) === Object.prototype);
23
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/rolldown-plugin-gjsify",
3
- "version": "0.4.28",
3
+ "version": "0.4.29",
4
4
  "description": "Rolldown / Rollup / Vite plugin orchestrator for GJS, Node, and Browser targets",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -48,11 +48,11 @@
48
48
  ],
49
49
  "license": "MIT",
50
50
  "dependencies": {
51
- "@gjsify/console": "^0.4.28",
52
- "@gjsify/resolve-npm": "^0.4.28",
53
- "@gjsify/rolldown-plugin-deepkit": "^0.4.28",
54
- "@gjsify/rolldown-plugin-pnp": "^0.4.28",
55
- "@gjsify/vite-plugin-blueprint": "^0.4.28",
51
+ "@gjsify/console": "^0.4.29",
52
+ "@gjsify/resolve-npm": "^0.4.29",
53
+ "@gjsify/rolldown-plugin-deepkit": "^0.4.29",
54
+ "@gjsify/rolldown-plugin-pnp": "^0.4.29",
55
+ "@gjsify/vite-plugin-blueprint": "^0.4.29",
56
56
  "@rollup/pluginutils": "^5.3.0",
57
57
  "acorn": "^8.16.0",
58
58
  "acorn-walk": "^8.3.5",
@@ -60,7 +60,7 @@
60
60
  "lightningcss": "^1.32.0"
61
61
  },
62
62
  "peerDependencies": {
63
- "@gjsify/lightningcss-native": "^0.4.28",
63
+ "@gjsify/lightningcss-native": "^0.4.29",
64
64
  "rolldown": "^1.0.0-rc.18"
65
65
  },
66
66
  "peerDependenciesMeta": {