mirinjs 0.1.0-alpha.22 → 0.1.0-alpha.24

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/runtime.ts +23 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mirinjs",
3
- "version": "0.1.0-alpha.22",
3
+ "version": "0.1.0-alpha.24",
4
4
  "description": "Build desktop apps with Bun, TypeScript, and Chromium (CEF). The Bun-native Electron alternative.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/runtime.ts CHANGED
@@ -118,6 +118,21 @@ function dispatch(raw: string): void {
118
118
  }
119
119
  }
120
120
 
121
+ /** Process-global boot marker. Module-level state won't do: a bundle carrying
122
+ * two mirinjs copies (workspace version skew) evaluates this module twice, and
123
+ * a second event poller on the shared native queue steals events from the
124
+ * first — the app's `ready` never fires and no window opens, with no error.
125
+ * `Symbol.for` is the one namespace both copies share. */
126
+ const BOOT_SLOT = Symbol.for("mirinjs.runtime.booted");
127
+
128
+ /** Claim the process-wide boot slot; false when another mirinjs copy holds it. */
129
+ export function claimBootSlot(): boolean {
130
+ const g = globalThis as Record<symbol, unknown>;
131
+ if (g[BOOT_SLOT]) return false;
132
+ g[BOOT_SLOT] = true;
133
+ return true;
134
+ }
135
+
121
136
  /** Boot the runtime from the Worker's workerData. No-op when run detached. */
122
137
  export function boot(): void {
123
138
  const data = (workerData ?? {}) as {
@@ -131,6 +146,14 @@ export function boot(): void {
131
146
  };
132
147
  const corePath = data.corePath ?? process.env.MIRIN_CORE;
133
148
  if (!corePath) return; // not under the host; the API stays detached
149
+ if (!claimBootSlot()) {
150
+ console.error(
151
+ "[mirin] refusing to boot a second mirinjs copy in this process — the bundle " +
152
+ "contains duplicate mirinjs installs (workspace packages pinning different " +
153
+ "versions?). This copy stays detached; align every mirinjs dependency to one version.",
154
+ );
155
+ return;
156
+ }
134
157
 
135
158
  const core = new Core(corePath);
136
159
  const rpc = new RpcServer();