@gjsify/rolldown-plugin-gjsify 0.27.0 → 0.28.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/lib/index.d.ts CHANGED
@@ -18,7 +18,7 @@ export { externalsPlugin } from './plugins/externals.js';
18
18
  export type { ExternalsPredicate, ExternalsPluginOptions } from './plugins/externals.js';
19
19
  export { unresolvedWorkspaceImportPlugin, classifyImport, isWorkspaceSpecifier, formatUnresolvedWorkspaceImport, buildReverseAliasIndex, UnresolvedWorkspaceImportError, } from './plugins/unresolved-workspace-import.js';
20
20
  export type { WorkspaceImportGuardOptions, WorkspaceImportGuardTarget, ImportVerdict, ClassifyImportInput, UnresolvedWorkspaceImportDetails, } from './plugins/unresolved-workspace-import.js';
21
- export { napiNodeAddonPlugin, resolveAddonPath, nearestPackageRoot, classifySpecifier, directNodeShim, nodeGypBuildShim, bindingsShim, napiRsShim, ADDON_FILTER_RE, isNapiRsPackageJson, isNapiRsSibling, detectNapiRsEntry, hostNapiRsTriple, AddonNotBuiltError, } from './plugins/napi-node-addon.js';
21
+ export { napiNodeAddonPlugin, resolveAddonPath, nearestPackageRoot, classifySpecifier, directNodeShim, nodeGypBuildShim, bindingsShim, napiRsShim, ADDON_FILTER_RE, isNapiRsPackageJson, isNapiRsSibling, isGjsifyNativeBridge, detectNapiRsEntry, hostNapiRsTriple, AddonNotBuiltError, } from './plugins/napi-node-addon.js';
22
22
  export type { NapiNodeAddonPluginOptions, AddonPackageJson } from './plugins/napi-node-addon.js';
23
23
  export { platformResolvePlugin, detectNativescriptPlatform, nativescriptPlatformDefines, } from './plugins/platform-resolve.js';
24
24
  export type { PlatformResolvePluginOptions, NativescriptPlatform } from './plugins/platform-resolve.js';
package/lib/index.js CHANGED
@@ -12,7 +12,7 @@ export { aliasPlugin } from './plugins/alias.js';
12
12
  export { gjsImportsEmptyPlugin } from './plugins/gjs-imports-empty.js';
13
13
  export { externalsPlugin } from './plugins/externals.js';
14
14
  export { unresolvedWorkspaceImportPlugin, classifyImport, isWorkspaceSpecifier, formatUnresolvedWorkspaceImport, buildReverseAliasIndex, UnresolvedWorkspaceImportError, } from './plugins/unresolved-workspace-import.js';
15
- export { napiNodeAddonPlugin, resolveAddonPath, nearestPackageRoot, classifySpecifier, directNodeShim, nodeGypBuildShim, bindingsShim, napiRsShim, ADDON_FILTER_RE, isNapiRsPackageJson, isNapiRsSibling, detectNapiRsEntry, hostNapiRsTriple, AddonNotBuiltError, } from './plugins/napi-node-addon.js';
15
+ export { napiNodeAddonPlugin, resolveAddonPath, nearestPackageRoot, classifySpecifier, directNodeShim, nodeGypBuildShim, bindingsShim, napiRsShim, ADDON_FILTER_RE, isNapiRsPackageJson, isNapiRsSibling, isGjsifyNativeBridge, detectNapiRsEntry, hostNapiRsTriple, AddonNotBuiltError, } from './plugins/napi-node-addon.js';
16
16
  export { platformResolvePlugin, detectNativescriptPlatform, nativescriptPlatformDefines, } from './plugins/platform-resolve.js';
17
17
  export * from './plugin.js';
18
18
  import { gjsifyPlugin } from './plugin.js';
@@ -67,8 +67,39 @@ export interface AddonPackageJson {
67
67
  exports?: unknown;
68
68
  browser?: string;
69
69
  napi?: unknown;
70
+ gjsify?: unknown;
70
71
  optionalDependencies?: Record<string, string>;
71
72
  }
73
+ /**
74
+ * Is this manifest a gjsify NATIVE BRIDGE whose prebuilds live in per-target
75
+ * sibling packages (ADR 0017) — `@gjsify/webgl` + `@gjsify/webgl-darwin-x64`, …?
76
+ *
77
+ * Such a bridge ships a GObject-Introspection typelib plus a `.so`/`.dylib`/`.dll`
78
+ * loaded through `gi://`, NEVER a Node-API `.node` addon, so it must never be
79
+ * routed through `loadAddon()`.
80
+ *
81
+ * It has to be excluded EXPLICITLY because the two conventions are
82
+ * indistinguishable by name: ADR 0017 spells a target `<os>-<arch>` and names the
83
+ * package `<self>-<os>-<arch>` in `optionalDependencies` — which is exactly
84
+ * napi-rs' `<self>-<triple>` sibling scheme whenever the target happens to be a
85
+ * name napi-rs also uses. On Linux the two vocabularies differ by the libc token
86
+ * (`linux-x64` vs napi-rs' `linux-x64-gnu`), so `hostNapiRsTriple()` never matched
87
+ * and nothing fired; on macOS napi-rs' triple IS `darwin-x64` / `darwin-arm64`,
88
+ * so every split bridge looked like a napi-rs package to
89
+ * {@link isNapiRsPackageJson} and {@link resolveNapiRsEntryAddon} then probed
90
+ * `ctx.resolve('@gjsify/webgl-darwin-x64')` — an artifact-only package with no JS
91
+ * entry at all. That probe does not return null: the `unresolved-workspace-import`
92
+ * guard (correctly) treats an unresolvable bare `@gjsify/*` as FATAL, so
93
+ * `gjsify build --app gjs` of any consumer of any split bridge died on darwin with
94
+ * "cannot resolve the workspace package" — invisible to every Linux CI job.
95
+ *
96
+ * `gjsify.platforms` is the right discriminator: it is the OS-axis declaration
97
+ * every native bridge carries (§ Runtime & platform model) and no napi-rs package
98
+ * has any reason to declare it.
99
+ *
100
+ * Exported for the unit tests.
101
+ */
102
+ export declare function isGjsifyNativeBridge(pkg: AddonPackageJson): boolean;
72
103
  /**
73
104
  * A package.json describes a napi-rs generated-loader package when EITHER
74
105
  * signal holds — both are package.json-level (not source sniffing):
@@ -384,6 +384,42 @@ export function classifySpecifier(source) {
384
384
  return { kind: 'napi-rs-candidate' };
385
385
  return null;
386
386
  }
387
+ /**
388
+ * Is this manifest a gjsify NATIVE BRIDGE whose prebuilds live in per-target
389
+ * sibling packages (ADR 0017) — `@gjsify/webgl` + `@gjsify/webgl-darwin-x64`, …?
390
+ *
391
+ * Such a bridge ships a GObject-Introspection typelib plus a `.so`/`.dylib`/`.dll`
392
+ * loaded through `gi://`, NEVER a Node-API `.node` addon, so it must never be
393
+ * routed through `loadAddon()`.
394
+ *
395
+ * It has to be excluded EXPLICITLY because the two conventions are
396
+ * indistinguishable by name: ADR 0017 spells a target `<os>-<arch>` and names the
397
+ * package `<self>-<os>-<arch>` in `optionalDependencies` — which is exactly
398
+ * napi-rs' `<self>-<triple>` sibling scheme whenever the target happens to be a
399
+ * name napi-rs also uses. On Linux the two vocabularies differ by the libc token
400
+ * (`linux-x64` vs napi-rs' `linux-x64-gnu`), so `hostNapiRsTriple()` never matched
401
+ * and nothing fired; on macOS napi-rs' triple IS `darwin-x64` / `darwin-arm64`,
402
+ * so every split bridge looked like a napi-rs package to
403
+ * {@link isNapiRsPackageJson} and {@link resolveNapiRsEntryAddon} then probed
404
+ * `ctx.resolve('@gjsify/webgl-darwin-x64')` — an artifact-only package with no JS
405
+ * entry at all. That probe does not return null: the `unresolved-workspace-import`
406
+ * guard (correctly) treats an unresolvable bare `@gjsify/*` as FATAL, so
407
+ * `gjsify build --app gjs` of any consumer of any split bridge died on darwin with
408
+ * "cannot resolve the workspace package" — invisible to every Linux CI job.
409
+ *
410
+ * `gjsify.platforms` is the right discriminator: it is the OS-axis declaration
411
+ * every native bridge carries (§ Runtime & platform model) and no napi-rs package
412
+ * has any reason to declare it.
413
+ *
414
+ * Exported for the unit tests.
415
+ */
416
+ export function isGjsifyNativeBridge(pkg) {
417
+ const gjsify = pkg?.gjsify;
418
+ if (gjsify === null || typeof gjsify !== 'object')
419
+ return false;
420
+ const { platforms, prebuilds } = gjsify;
421
+ return Array.isArray(platforms) || typeof prebuilds === 'string';
422
+ }
387
423
  /**
388
424
  * A package.json describes a napi-rs generated-loader package when EITHER
389
425
  * signal holds — both are package.json-level (not source sniffing):
@@ -576,6 +612,10 @@ function napiSiblingPrefixes(pkg) {
576
612
  export function isNapiRsSibling(pkg, dep) {
577
613
  if (!NAPI_RS_TRIPLE_RE.test(dep))
578
614
  return false;
615
+ // A gjsify ADR-0017 platform package wears the same name — see
616
+ // {@link isGjsifyNativeBridge} for the darwin-only build break that caused.
617
+ if (isGjsifyNativeBridge(pkg))
618
+ return false;
579
619
  return napiSiblingPrefixes(pkg).some((prefix) => dep.startsWith(`${prefix}-`));
580
620
  }
581
621
  /**
@@ -650,7 +690,22 @@ async function resolveNapiRsEntryAddon(ctx, pkgRoot, pkg, importer) {
650
690
  // loaders do, so this matches the binary Node would have loaded.
651
691
  const ordered = triple === null ? siblings : siblings.filter((dep) => dep.endsWith(`-${triple}`));
652
692
  for (const dep of ordered) {
653
- const resolved = await ctx.resolve(dep, importer, { skipSelf: true });
693
+ // This resolve is a QUESTION ("is a host-triple binary installed?"), but it
694
+ // can THROW rather than answer: `skipSelf` skips only THIS plugin, so the
695
+ // `unresolved-workspace-import` guard still runs at `order:'post'` and
696
+ // (correctly, for a real import) makes an unresolvable bare `@gjsify/*`
697
+ // FATAL. A misread sibling name then kills the whole build instead of
698
+ // declining — measured on darwin, where every ADR-0017 platform package
699
+ // matched this path. The name check above is the fix; this keeps the class
700
+ // from ever being fatal again, and says which specifier was asked about.
701
+ let resolved = null;
702
+ try {
703
+ resolved = await ctx.resolve(dep, importer, { skipSelf: true });
704
+ }
705
+ catch (err) {
706
+ warnSafe(ctx, `[gjsify-napi] probing the platform sibling "${dep}" of "${pkg.name ?? pkgRoot}" failed; not rewriting its entry (${err instanceof Error ? err.message.split('\n')[0] : String(err)})`);
707
+ continue;
708
+ }
654
709
  if (!resolved)
655
710
  continue;
656
711
  const abs = rawAddonPath(resolved.id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/rolldown-plugin-gjsify",
3
- "version": "0.27.0",
3
+ "version": "0.28.0",
4
4
  "description": "Rolldown / Rollup / Vite plugin orchestrator for GJS, Node, and Browser targets",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -35,7 +35,7 @@
35
35
  "scripts": {
36
36
  "clear": "gjsify clear lib tsconfig.tsbuildinfo",
37
37
  "check": "gjsify tsc --noEmit",
38
- "build": "tsc"
38
+ "build": "gjsify tsc"
39
39
  },
40
40
  "repository": {
41
41
  "type": "git",
@@ -55,11 +55,11 @@
55
55
  ],
56
56
  "license": "MIT",
57
57
  "dependencies": {
58
- "@gjsify/console": "^0.27.0",
59
- "@gjsify/resolve-npm": "^0.27.0",
60
- "@gjsify/rolldown-plugin-deepkit": "^0.27.0",
61
- "@gjsify/rolldown-plugin-pnp": "^0.27.0",
62
- "@gjsify/vite-plugin-blueprint": "^0.27.0",
58
+ "@gjsify/console": "^0.28.0",
59
+ "@gjsify/resolve-npm": "^0.28.0",
60
+ "@gjsify/rolldown-plugin-deepkit": "^0.28.0",
61
+ "@gjsify/rolldown-plugin-pnp": "^0.28.0",
62
+ "@gjsify/vite-plugin-blueprint": "^0.28.0",
63
63
  "@rollup/pluginutils": "^5.4.0",
64
64
  "acorn": "^8.17.0",
65
65
  "acorn-walk": "^8.3.5",
@@ -68,7 +68,7 @@
68
68
  "sass": "^1.101.0"
69
69
  },
70
70
  "peerDependencies": {
71
- "@gjsify/lightningcss-native": "^0.27.0",
71
+ "@gjsify/lightningcss-native": "^0.28.0",
72
72
  "rolldown": "^1.1.4"
73
73
  },
74
74
  "peerDependenciesMeta": {