@gjsify/rolldown-native 0.52.0 → 0.53.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/README.md +15 -21
- package/lib/esm/plugins.js +1 -1
- package/lib/types/index.d.ts +6 -0
- package/lib/types/plugins.d.ts +13 -0
- package/meson.build +7 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -71,32 +71,26 @@ the lock — regenerate it in the same commit as the submodule pin and the npm `
|
|
|
71
71
|
| `linux-x64` | ✅ `.so` + `.gir` + `.typelib` | native runner |
|
|
72
72
|
| `linux-arm64` | ✅ | native runner |
|
|
73
73
|
| `linux-ppc64`, `linux-s390x`, `linux-riscv64` | ❌ | not built — the rolldown crate graph is too slow under QEMU |
|
|
74
|
-
| macOS (`darwin-arm64`) |
|
|
75
|
-
| macOS (`darwin-x64`) |
|
|
74
|
+
| macOS (`darwin-arm64`) | ✅ `.dylib` + `.gir` + `.typelib` | native runner |
|
|
75
|
+
| macOS (`darwin-x64`) | ✅ | native runner |
|
|
76
76
|
| Windows | ❌ | — no Vala/GI bridge in this repo targets Windows |
|
|
77
77
|
|
|
78
78
|
All prebuilds are produced by [`.github/workflows/prebuilds.yml`](../../../.github/workflows/prebuilds.yml)
|
|
79
79
|
and committed back to the repository.
|
|
80
80
|
|
|
81
|
-
###
|
|
82
|
-
|
|
83
|
-
The **
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
unproven — a cross-`check` does not exercise linking, the GIR/typelib step, or `gi://` load.
|
|
95
|
-
|
|
96
|
-
Because `@gjsify/rolldown-native` is the only bundler engine available to `gjsify build`
|
|
97
|
-
under GJS, it is the last package gating a Node-free gjsify toolchain on macOS —
|
|
98
|
-
`@gjsify/lightningcss-native` and `@gjsify/oxfmt-native` already ship `darwin-arm64`
|
|
99
|
-
prebuilds.
|
|
81
|
+
### Runtime system dependency: json-glib
|
|
82
|
+
|
|
83
|
+
The prebuild links **json-glib** (`BundlerSession` peeks at the hook name and request id of each
|
|
84
|
+
Rust-emitted JSON envelope before routing it), and it is a SYSTEM library on every target, like
|
|
85
|
+
GLib itself: `libjson-glib-1.0.so.0` on Linux, `@rpath/libjson-glib-1.0.0.dylib` on macOS, where
|
|
86
|
+
the rpath list ends in the Homebrew prefix ([docs/prebuilds.md](../../../docs/prebuilds.md)). Homebrew's
|
|
87
|
+
`gjs` formula does not pull it in, so a Mac needs `brew install json-glib`; `gjsify system-check`
|
|
88
|
+
lists it with the install command for the host.
|
|
89
|
+
|
|
90
|
+
Without it the typelib still resolves and the library fails to open. GJS reports that at the first
|
|
91
|
+
class access as `Unsupported type void, deriving from fundamental void`, so `gjsify build` probes
|
|
92
|
+
the library before choosing the engine (`probeNativeLibrary()` in `@gjsify/utils/core`) and prints
|
|
93
|
+
the file that failed, the dependency the loader named, and the install command.
|
|
100
94
|
|
|
101
95
|
### Wakeup channel (implementation note)
|
|
102
96
|
|
package/lib/esm/plugins.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import"./_virtual/_rolldown/runtime.js";import{loadNativeRolldown as e}from"./index.js";function getGLib(){let e=globalThis.imports?.gi;if(!e||!e.GLib)throw Error(`@gjsify/rolldown-native: GLib not available (not running under GJS?)`);return e.GLib}const enc=e=>getGLib().Bytes.new(new TextEncoder().encode(e)),dec=e=>new TextDecoder().decode(e.get_data()??new Uint8Array),t=[`load`,`transform`,`resolveId`,`renderChunk`,`banner`,`footer`,`intro`,`outro`,`buildStart`,`buildEnd`,`generateBundle`,`writeBundle`,`closeBundle`];function pluginMeta(e){let n=t.filter(t=>typeof e[t]==`function`),r={name:e.name,hooks:n};return e.idFilter&&(r.idFilter=e.idFilter),r}const n=new Set;function isResolveMiss(e){return e.startsWith(`NotFound(`)}var HookErrorLog=class{entries=[];record(e,t){this.entries.push({...e,message:t})}format(){if(this.entries.length===0)return``;let e=this.entries.slice(0,8),t=e.map(({plugin:e,hook:t,message:n})=>` [plugin ${e}] ${t}: ${n}`),n=this.entries.length-e.length;return n>0&&t.push(` … and ${n} more`),`${this.entries.length===1?`1 plugin hook failed during this build:`:`${this.entries.length} plugin hooks failed during this build:`}\n${t.join(`
|
|
2
|
-
`)}`}};function bundleWithPlugins(t,r){let i=e();if(!i)return Promise.reject(Error(`@gjsify/rolldown-native: prebuild not available`));let a=new i.BundlerSession;n.add(a);let o=new HookErrorLog,s=new Map;a.connect(`context_response`,(e,t,n)=>{let r=
|
|
2
|
+
`)}`}};function bundleWithPlugins(t,r){let i=e();if(!i)return Promise.reject(Error(`@gjsify/rolldown-native: prebuild not available`));let a=new i.BundlerSession;n.add(a);let o=new HookErrorLog,s=new Set,c=new Map;a.connect(`context_response`,(e,t,n)=>{let r=c.get(t);if(!r)return;c.delete(t);let i;try{i=JSON.parse(dec(n))}catch(e){r.reject(e instanceof Error?e:Error(String(e)));return}i.error&&isResolveMiss(i.error)?r.resolve(null):i.error?r.reject(Error(i.error)):i.id?r.resolve({id:i.id,external:i.external??!1}):r.resolve(null)});function makeContext(e){return{addWatchFile(e){s.add(e)},resolve(t,n,r){return new Promise((i,o)=>{let s=a.context_resolve(e,enc(JSON.stringify({specifier:t,importer:n,skipSelf:r?.skipSelf??!0,isEntry:r?.isEntry??!1})));if(s===0){o(Error(`@gjsify/rolldown-native: ctx.resolve('${t}') failed — parent req_id ${e} unknown`));return}c.set(s,{resolve:i,reject:o})})},warn(e){a.context_warn(enc(e))},error(e){throw Error(e)}}}a.connect(`hook_requested`,(e,t,n,r,i)=>{dispatchHook(t,n,r,i)});async function dispatchHook(e,t,n,i){let o={plugin:r[n]?.name??`#${n}`,hook:e},s;try{s=JSON.parse(dec(i))}catch(e){respondError(t,e,o);return}let c=r[n];if(!c){respondError(t,Error(`@gjsify/rolldown-native: unknown plugin index ${n}`),o);return}let l=makeContext(t);try{if(e===`transform`&&c.transform){let e=s,n=a.take_request_payload(t);if(n===null)throw Error(`@gjsify/rolldown-native: transform request for ${e.id} missing payload bytes`);let r=dec(n);respondTransform(t,await c.transform.call(l,r,e.id,e.moduleType),o);return}respondOk(t,await runHook(c,e,s,l))}catch(e){respondError(t,e,o)}}function respondOk(e,t){let n=t==null?{kind:`skip`}:{kind:`ok`,value:t};a.respond(e,enc(JSON.stringify(n)))}function respondTransform(e,t,n){if(t==null){a.respond(e,enc(JSON.stringify({kind:`skip`})));return}let r,i;if(typeof t==`string`)r=t;else if(typeof t==`object`){let e=t;r=e.code,i=e.moduleType}if(typeof r!=`string`){a.respond(e,enc(JSON.stringify({kind:`skip`})));return}let o=getGLib().Bytes.new(new TextEncoder().encode(r));if(!a.set_response_payload(e,o)){respondError(e,Error(`@gjsify/rolldown-native: failed to stash transform response payload for reqId ${e}`),n);return}a.respond(e,enc(JSON.stringify({kind:`ok`,value:i===void 0?{hasCodeBytes:!0}:{hasCodeBytes:!0,moduleType:i}})))}function respondError(e,t,n){let r=t instanceof Error?t:Error(String(t));o.record(n,r.message),a.respond(e,enc(JSON.stringify({kind:`error`,message:r.message,stack:r.stack})))}let closeSession=()=>{n.delete(a);let e=a;try{e.close?.()}catch{}};return new Promise((e,n)=>{a.connect(`completed`,(t,r)=>{try{e({...JSON.parse(dec(r)),watchedFiles:[...s]})}catch(e){n(e instanceof Error?e:Error(String(e)))}}),a.connect(`error_occurred`,(e,t)=>{let r=o.format();n(Error(r?`${t}\n${r}`:t))});try{a.start(enc(JSON.stringify({options:t,plugins:r.map(pluginMeta)})))}catch(e){n(e instanceof Error?e:Error(String(e)))}}).finally(closeSession)}async function runHook(e,t,n,r){switch(t){case`load`:return e.load?normalizeLoadResult(await e.load.call(r,n.id)):null;case`transform`:return null;case`resolveId`:{if(!e.resolveId)return null;let t=n;return normalizeResolveIdResult(await e.resolveId.call(r,t.specifier,t.importer,{isEntry:t.isEntry}))}case`renderChunk`:{if(!e.renderChunk)return null;let t=n;return normalizeRenderChunkResult(await e.renderChunk.call(r,t.code,{fileName:t.fileName,name:t.name,isEntry:t.isEntry}))}case`banner`:case`footer`:case`intro`:case`outro`:{let i=e[t];if(!i)return null;let a=n;return normalizeAddonResult(await i.call(r,{fileName:a.fileName,name:a.name,isEntry:a.isEntry}))}case`buildStart`:case`buildEnd`:case`generateBundle`:case`writeBundle`:case`closeBundle`:{let n=e[t];return n&&await n.call(r),null}default:throw Error(`@gjsify/rolldown-native: unknown hook '${t}'`)}}function normalizeLoadResult(e){return e==null?null:typeof e==`string`?{code:e}:{code:e.code,moduleType:e.moduleType}}function normalizeResolveIdResult(e){return e==null?null:typeof e==`string`?{id:e}:{id:e.id,external:e.external}}function normalizeRenderChunkResult(e){return e==null?null:typeof e==`string`?{code:e}:{code:e.code}}function normalizeAddonResult(e){return e==null?null:typeof e==`string`?e:e.text}export{bundleWithPlugins,isResolveMiss};
|
package/lib/types/index.d.ts
CHANGED
|
@@ -49,6 +49,12 @@ export type BundleOutputItem = BundleChunk | BundleAsset;
|
|
|
49
49
|
export interface BundleResult {
|
|
50
50
|
warnings: string[];
|
|
51
51
|
output: BundleOutputItem[];
|
|
52
|
+
/**
|
|
53
|
+
* Files a plugin declared with `this.addWatchFile` — npm rolldown's
|
|
54
|
+
* `RolldownBuild.watchFiles`, collected here because this engine has no
|
|
55
|
+
* watcher to feed. Absent on a `bundle()` result that declares none.
|
|
56
|
+
*/
|
|
57
|
+
watchedFiles?: string[];
|
|
52
58
|
}
|
|
53
59
|
export { bundleWithPlugins, isResolveMiss, type NativePlugin, type NativePluginContext, type PluginIdFilter, type LoadHookHandler, type TransformHookHandler, type ResolveIdHookHandler, type RenderChunkHookHandler, type AddonHookHandler, type LifecycleHookHandler, } from './plugins.js';
|
|
54
60
|
/**
|
package/lib/types/plugins.d.ts
CHANGED
|
@@ -24,6 +24,19 @@ export interface NativePluginContext {
|
|
|
24
24
|
id: string;
|
|
25
25
|
external: boolean;
|
|
26
26
|
} | null>;
|
|
27
|
+
/**
|
|
28
|
+
* Register a file the output depends on but the bundler never made a module
|
|
29
|
+
* — rolldown's `this.addWatchFile`. Collected into the result's
|
|
30
|
+
* `watchedFiles`.
|
|
31
|
+
*
|
|
32
|
+
* The native engine has no watcher to feed and the Rust side never asked
|
|
33
|
+
* for one, so the list goes nowhere but the caller: `gjsify test` judges its
|
|
34
|
+
* bundle against it. An older published copy of this package is what a host
|
|
35
|
+
* may actually load (the CLI resolves the engine through several anchors),
|
|
36
|
+
* so a plugin must feature-detect this — a build must not fail over
|
|
37
|
+
* bookkeeping, and a miss is reported rather than silent.
|
|
38
|
+
*/
|
|
39
|
+
addWatchFile(id: string): void;
|
|
27
40
|
/** Append a warning to the bundle's warnings list. */
|
|
28
41
|
warn(message: string): void;
|
|
29
42
|
/** Throw with `message` — caught at the dispatch boundary and
|
package/meson.build
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# `buildtype=plain` = NO `-g`. ld64 emits a DEBUG MAP into any image whose objects
|
|
2
|
+
# carry DWARF — one `N_OSO` stab per object, holding its MTIME — so with `-g` every
|
|
3
|
+
# rebuild of this commit differed in bytes (plus the `LC_UUID` and the ad-hoc signature
|
|
4
|
+
# computed over them) and `commit-prebuilds` re-committed all 16 darwin dylibs. That map
|
|
5
|
+
# names intermediate `.o` files no consumer can have. Why: docs/prebuilds.md.
|
|
6
|
+
project('GjsifyRolldown', ['c', 'vala'], version: '1.0',
|
|
7
|
+
default_options: ['buildtype=plain'])
|
|
2
8
|
|
|
3
9
|
# Required system packages (Fedora 43+):
|
|
4
10
|
# dnf install vala meson ninja-build cargo
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/rolldown-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.0",
|
|
4
4
|
"description": "Phase D-2 POC: Vala/GObject + Rust cdylib bridge to rolldown for GJS. Wraps `rolldown::Bundler::generate()` (async, tokio) in a per-call current-thread runtime so JS sees a sync `bundle()` call. JSON-encoded BundlerOptions in, JSON-encoded BundleOutput out — the boundary stays small even though rolldown's option surface is enormous. POC scope: no JS plugins (Phase B), no watch/HMR, no incremental builds. Companion to `@gjsify/lightningcss-native`; together they remove the last two Rust-crate runtime blockers from the gjsify build pipeline (Phase D-3 unblock).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/esm/index.js",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"@girs/gobject-2.0": "5.4.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@gjsify/cli": "^0.
|
|
61
|
+
"@gjsify/cli": "^0.53.0",
|
|
62
62
|
"@types/node": "^25.9.2",
|
|
63
63
|
"typescript": "^6.0.3"
|
|
64
64
|
},
|
|
@@ -74,9 +74,9 @@
|
|
|
74
74
|
},
|
|
75
75
|
"homepage": "https://github.com/gjsify/gjsify/tree/main/packages/infra/rolldown-native#readme",
|
|
76
76
|
"optionalDependencies": {
|
|
77
|
-
"@gjsify/rolldown-native-darwin-arm64": "0.
|
|
78
|
-
"@gjsify/rolldown-native-darwin-x64": "0.
|
|
79
|
-
"@gjsify/rolldown-native-linux-arm64": "0.
|
|
80
|
-
"@gjsify/rolldown-native-linux-x64": "0.
|
|
77
|
+
"@gjsify/rolldown-native-darwin-arm64": "0.53.0",
|
|
78
|
+
"@gjsify/rolldown-native-darwin-x64": "0.53.0",
|
|
79
|
+
"@gjsify/rolldown-native-linux-arm64": "0.53.0",
|
|
80
|
+
"@gjsify/rolldown-native-linux-x64": "0.53.0"
|
|
81
81
|
}
|
|
82
82
|
}
|