@incajs/cli 0.0.4 → 0.0.5

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 CHANGED
@@ -57,11 +57,13 @@ once it is packaged.
57
57
 
58
58
  ## Requirements
59
59
 
60
- `inca`'s host binary is pulled in automatically as a platform-specific
61
- optional dependency (Linux and macOS on x64/arm64; Windows isn't
62
- supported yet) — neither Cargo nor Rust are needed. Set `INCA_HOST_BIN`
63
- to use a specific binary instead, e.g. on a platform with no published
64
- one yet, or a custom build.
60
+ A prebuilt binary is pulled in automatically as a platform-specific
61
+ optional dependency — neither Cargo nor Rust are needed. See
62
+ [Host binary](https://tom96da.github.io/incajs/guide/#host-binary) for
63
+ per-platform support.
64
+
65
+ Set `INCA_HOST_BIN` to use a specific binary instead, e.g. on a
66
+ platform with no published one yet, or a custom build.
65
67
 
66
68
  ## How it works
67
69
 
@@ -3,38 +3,6 @@ export interface Watcher {
3
3
  /** Stops watching and releases the underlying build process. */
4
4
  close(): Promise<void>;
5
5
  }
6
- /** Options for {@link Bundler.watch}. */
7
- export interface BundlerOptions {
8
- /** The app's own entry point — may import `.vue` files. */
9
- entry: string;
10
- /** Where the build's output is written. */
11
- outDir: string;
12
- /**
13
- * Values the built app carries for `inca-host` to read — its name, id
14
- * and window. Any JSON-serializable object.
15
- */
16
- runtimeConfig?: unknown;
17
- /** `"development"` keeps a framework's own warnings; `"production"` strips them. */
18
- mode: "development" | "production";
19
- /** Called after each successful (re)build, with what it wrote. */
20
- onBuild: (output: BuildOutput) => void;
21
- /** Called instead of `onBuild` when a (re)build fails. */
22
- onError: (error: {
23
- message: string;
24
- stack: string | null;
25
- code?: string | null;
26
- }) => void;
27
- /** Where the bundler's own output goes. Defaults to `process.stdout`. */
28
- stdout?: NodeJS.WritableStream;
29
- /** Where the bundler's warnings and errors go. Defaults to `process.stderr`. */
30
- stderr?: NodeJS.WritableStream;
31
- /**
32
- * Drops the bundler's progress output and size report, leaving the
33
- * per-build summary. Set it when the build has to stay silent: part of
34
- * that output goes to the process's own stdout, not to `stdout` above.
35
- */
36
- quiet?: boolean;
37
- }
38
6
  /** Options for {@link Bundler.build}. */
39
7
  export interface BuildOptions {
40
8
  /** The app's own entry point — may import `.vue` files. */
@@ -57,6 +25,19 @@ export interface BuildOptions {
57
25
  */
58
26
  quiet?: boolean;
59
27
  }
28
+ /** Options for {@link Bundler.watch}. */
29
+ export interface BundlerOptions extends BuildOptions {
30
+ /** `"development"` keeps a framework's own warnings; `"production"` strips them. */
31
+ mode: "development" | "production";
32
+ /** Called after each successful (re)build, with what it wrote. */
33
+ onBuild: (output: BuildOutput) => void;
34
+ /** Called instead of `onBuild` when a (re)build fails. */
35
+ onError: (error: {
36
+ message: string;
37
+ stack: string | null;
38
+ code?: string | null;
39
+ }) => void;
40
+ }
60
41
  /** What a build wrote — the result of {@link Bundler.build}, and every {@link BundlerOptions.onBuild} call. */
61
42
  export interface BuildOutput {
62
43
  /** Directory holding every file this build emitted. */
@@ -1,5 +1,4 @@
1
1
  import { BuildOptions, BuildOutput } from '../types.mts';
2
- export type { BuildOptions, BuildOutput } from '../types.mts';
3
2
  /**
4
3
  * Builds `entry` into a minified, production build under `outDir` once, and
5
4
  * rejects on failure rather than reporting it through a callback. Never
@@ -1,4 +1,5 @@
1
1
  import { Plugin } from 'vite';
2
+ import { BuildOutput } from '../types.mts';
2
3
  /** What one (re)build actually wrote, relative to its own `outDir`. */
3
4
  export interface CapturedOutput {
4
5
  /** The emitted chunk marked as this build's entry. */
@@ -6,6 +7,8 @@ export interface CapturedOutput {
6
7
  /** Every emitted file, as the bundler reported it. */
7
8
  files: readonly string[];
8
9
  }
10
+ /** Resolves `captured`'s paths against `outDir` into a {@link BuildOutput}. */
11
+ export declare function toBuildOutput(outDir: string, captured: CapturedOutput, changed?: BuildOutput["changed"]): BuildOutput;
9
12
  /**
10
13
  * A Vite plugin reporting `sink` the files a build wrote once they land on
11
14
  * disk, via `writeBundle` — the one hook that fires uniformly for a
@@ -1,5 +1,4 @@
1
1
  import { BundlerOptions, Watcher } from '../types.mts';
2
- export type { Watcher } from '../types.mts';
3
2
  /**
4
3
  * Builds `entry` into a build under `outDir` and rebuilds it on every
5
4
  * change, calling `onBuild` with what each rebuild wrote. Never starts,
package/dist/cli.js CHANGED
@@ -9,57 +9,57 @@ import { createRequire as v } from "node:module";
9
9
  import { spawn as y } from "node:child_process";
10
10
  import { once as b } from "node:events";
11
11
  import x from "node:readline";
12
- import { setTimeout as ee } from "node:timers/promises";
12
+ import { setTimeout as S } from "node:timers/promises";
13
13
  //#region src/error.mts
14
- var S = class extends Error {
14
+ var C = class extends Error {
15
15
  code;
16
16
  name = "IncaError";
17
17
  constructor(e, t) {
18
18
  super(t), this.code = e;
19
19
  }
20
- }, te = {
20
+ }, ee = {
21
21
  name: "inca",
22
22
  packageJson: "inca",
23
23
  rcFile: !1,
24
24
  globalRc: !1,
25
25
  giget: !1,
26
26
  extend: !1
27
- }, ne = /[/\\:*?"<>|\0]/;
28
- function re(e) {
29
- return e === e.trim() && e !== "" && e !== "." && e !== ".." && !ne.test(e);
27
+ }, te = /[/\\:*?"<>|\0]/;
28
+ function ne(e) {
29
+ return e === e.trim() && e !== "" && e !== "." && e !== ".." && !te.test(e);
30
30
  }
31
- function C(e) {
32
- if (!(typeof e == "string" && re(e))) throw new S("ERR_INCA_PRODUCT_NAME_INVALID", `${JSON.stringify(e)} can't name a directory — set a "productName" in inca.config.ts with no leading or trailing space, and none of \`/\\:*?"<>|\``);
31
+ function w(e) {
32
+ if (!(typeof e == "string" && ne(e))) throw new C("ERR_INCA_PRODUCT_NAME_INVALID", `${JSON.stringify(e)} can't name a directory — set a "productName" in inca.config.ts with no leading or trailing space, and none of \`/\\:*?"<>|\``);
33
33
  }
34
- async function w(e) {
34
+ async function T(e) {
35
35
  let { config: t, layers: r } = await n({
36
36
  cwd: e,
37
- ...te
37
+ ...ee
38
38
  }), i = r?.find((e) => e.configFile === "package.json");
39
39
  return {
40
40
  config: t,
41
41
  usedPackageJsonKey: Object.keys(i?.config ?? {}).length > 0
42
42
  };
43
43
  }
44
- async function T(e) {
45
- let { config: t } = await w(e);
44
+ async function E(e) {
45
+ let { config: t } = await T(e);
46
46
  return {
47
47
  entry: t.entry ? a.resolve(e, t.entry) : void 0,
48
48
  outDir: a.resolve(e, t.outDir ?? i.outDir)
49
49
  };
50
50
  }
51
- async function E(e) {
51
+ async function D(e) {
52
52
  let n = a.join(e, "package.json"), s;
53
53
  try {
54
54
  s = await d(n, "utf8");
55
55
  } catch {
56
- throw new S("ERR_INCA_PACKAGE_JSON_NOT_FOUND", `no package.json found at ${n}`);
56
+ throw new C("ERR_INCA_PACKAGE_JSON_NOT_FOUND", `no package.json found at ${n}`);
57
57
  }
58
- let c = JSON.parse(s), { config: l, usedPackageJsonKey: u } = await w(e), f = l.productName ?? r(c.name);
59
- if (!f) throw new S("ERR_INCA_PRODUCT_NAME_MISSING", `${n} needs a "name", or "productName" in inca.config.ts`);
60
- C(f);
58
+ let c = JSON.parse(s), { config: l, usedPackageJsonKey: u } = await T(e), f = l.productName ?? r(c.name);
59
+ if (!f) throw new C("ERR_INCA_PRODUCT_NAME_MISSING", `${n} needs a "name", or "productName" in inca.config.ts`);
60
+ w(f);
61
61
  let p = l.version ?? c.version ?? i.version, m = l.identifier ?? t(f), h;
62
- if (l.icon && (h = a.resolve(e, l.icon), !o(h))) throw new S("ERR_INCA_ICON_NOT_FOUND", `"icon" points to ${h}, which doesn't exist`);
62
+ if (l.icon && (h = a.resolve(e, l.icon), !o(h))) throw new C("ERR_INCA_ICON_NOT_FOUND", `"icon" points to ${h}, which doesn't exist`);
63
63
  let g = l.entry ? a.resolve(e, l.entry) : void 0, _ = a.resolve(e, l.outDir ?? i.outDir);
64
64
  return {
65
65
  productName: f,
@@ -73,20 +73,20 @@ async function E(e) {
73
73
  usedPackageJsonKey: u
74
74
  };
75
75
  }
76
- function D(e) {
76
+ function O(e) {
77
77
  return {
78
78
  name: e.productName,
79
79
  identifier: e.identifier,
80
80
  window: e.window
81
81
  };
82
82
  }
83
- async function O(e) {
84
- let { config: n } = await w(e), i = {};
83
+ async function k(e) {
84
+ let { config: n } = await T(e), i = {};
85
85
  try {
86
86
  i = JSON.parse(await d(a.join(e, "package.json"), "utf8"));
87
87
  } catch {}
88
88
  let o = n.productName ?? r(i.name);
89
- o && C(o);
89
+ o && w(o);
90
90
  let s = {
91
91
  name: o,
92
92
  identifier: n.identifier ?? (o ? t(o) : void 0),
@@ -96,12 +96,20 @@ async function O(e) {
96
96
  }
97
97
  //#endregion
98
98
  //#region src/adapter/vite/captureOutput.mts
99
- function ie(e) {
99
+ function A(e, t, n) {
100
+ return {
101
+ outDir: e,
102
+ entryFile: a.join(e, t.entryFile),
103
+ files: t.files,
104
+ changed: n
105
+ };
106
+ }
107
+ function re(e) {
100
108
  return {
101
109
  name: "inca:capture-output",
102
110
  writeBundle(t, n) {
103
111
  let r = Object.keys(n), i = Object.values(n).find((e) => e.type === "chunk" && e.isEntry);
104
- if (!i) throw new S("ERR_INCA_BUILD_NO_ENTRY_CHUNK", "build produced no entry chunk");
112
+ if (!i) throw new C("ERR_INCA_BUILD_NO_ENTRY_CHUNK", "build produced no entry chunk");
105
113
  e({
106
114
  entryFile: i.fileName,
107
115
  files: r
@@ -111,15 +119,15 @@ function ie(e) {
111
119
  }
112
120
  //#endregion
113
121
  //#region src/adapter/vite/emitConfig.mts
114
- var ae = "inca.json";
115
- function oe(e) {
122
+ var ie = "inca.json";
123
+ function ae(e) {
116
124
  let t = JSON.stringify(e, void 0, 2), n = t === void 0 || t === "{}";
117
125
  return {
118
126
  name: "inca:emit-config",
119
127
  generateBundle() {
120
128
  n || this.emitFile({
121
129
  type: "asset",
122
- fileName: ae,
130
+ fileName: ie,
123
131
  source: `${t}\n`
124
132
  });
125
133
  }
@@ -127,8 +135,8 @@ function oe(e) {
127
135
  }
128
136
  //#endregion
129
137
  //#region src/adapter/vite/logger.mts
130
- var se = "Build failed with ";
131
- function k(e, t) {
138
+ var oe = "Build failed with ";
139
+ function se(e, t) {
132
140
  let n = /* @__PURE__ */ new WeakSet(), r = /* @__PURE__ */ new Set(), i = {
133
141
  hasWarned: !1,
134
142
  info(t) {
@@ -141,7 +149,7 @@ function k(e, t) {
141
149
  r.has(e) || (r.add(e), i.warn(e));
142
150
  },
143
151
  error(e, r) {
144
- i.hasWarned = !0, r?.error && n.add(r.error), !e.includes(se) && t.write(`${e.replace(/\n\s+at .*/g, "")}\n`);
152
+ i.hasWarned = !0, r?.error && n.add(r.error), !e.includes(oe) && t.write(`${e.replace(/\n\s+at .*/g, "")}\n`);
145
153
  },
146
154
  clearScreen() {},
147
155
  hasErrorLogged(e) {
@@ -171,27 +179,27 @@ function ue(e = le) {
171
179
  let r = e.find((e) => e.matches(n));
172
180
  if (!r) return null;
173
181
  let i = a.relative(process.cwd(), n.split("?")[0] ?? n);
174
- throw new S(r.code, `${r.code}: ${i} uses ${r.name}, unsupported for now: ${r.hint}`);
182
+ throw new C(r.code, `${r.code}: ${i} uses ${r.name}, unsupported for now: ${r.hint}`);
175
183
  }
176
184
  };
177
185
  }
178
186
  //#endregion
179
187
  //#region src/adapter/vite/config.mts
180
188
  var de = "bundle.js";
181
- function A({ entry: e, outDir: t, mode: n, watch: r, onOutput: i, stdout: o, stderr: s, quiet: c, runtimeConfig: l }) {
189
+ function j({ entry: e, outDir: t, mode: n, watch: r, onOutput: i, stdout: o, stderr: s, quiet: c, runtimeConfig: l }) {
182
190
  return {
183
191
  configFile: !1,
184
192
  root: a.dirname(e),
185
193
  mode: n,
186
194
  clearScreen: !1,
187
195
  logLevel: c ? "silent" : "info",
188
- customLogger: k(o, s),
196
+ customLogger: se(o, s),
189
197
  define: { "process.env.NODE_ENV": JSON.stringify(n) },
190
198
  plugins: [
191
199
  _({ template: { compilerOptions: { runtimeModuleName: "@vue/runtime-core" } } }),
192
200
  ue(),
193
- oe(l),
194
- ie(i)
201
+ ae(l),
202
+ re(i)
195
203
  ],
196
204
  build: {
197
205
  lib: {
@@ -212,9 +220,9 @@ function A({ entry: e, outDir: t, mode: n, watch: r, onOutput: i, stdout: o, std
212
220
  }
213
221
  //#endregion
214
222
  //#region src/adapter/vite/build.mts
215
- async function fe({ entry: e, outDir: t, runtimeConfig: n, stdout: r = process.stdout, stderr: i = process.stderr, quiet: o = !1 }) {
216
- let s;
217
- if (await g(A({
223
+ async function fe({ entry: e, outDir: t, runtimeConfig: n, stdout: r = process.stdout, stderr: i = process.stderr, quiet: a = !1 }) {
224
+ let o;
225
+ if (await g(j({
218
226
  entry: e,
219
227
  outDir: t,
220
228
  runtimeConfig: n,
@@ -222,50 +230,46 @@ async function fe({ entry: e, outDir: t, runtimeConfig: n, stdout: r = process.s
222
230
  watch: !1,
223
231
  stdout: r,
224
232
  stderr: i,
225
- quiet: o,
233
+ quiet: a,
226
234
  onOutput: (e) => {
227
- s = {
228
- outDir: t,
229
- entryFile: a.join(t, e.entryFile),
230
- files: e.files
231
- };
235
+ o = A(t, e);
232
236
  }
233
- })), !s) throw new S("ERR_INCA_BUILD_NO_OUTPUT", "build produced no output");
234
- return s;
237
+ })), !o) throw new C("ERR_INCA_BUILD_NO_OUTPUT", "build produced no output");
238
+ return o;
235
239
  }
236
240
  //#endregion
237
241
  //#region src/dev-client/hostBin.mts
238
- var j = "INCA_HOST_BIN";
239
- function M() {
242
+ var M = "INCA_HOST_BIN";
243
+ function N() {
240
244
  let e = process.platform === "darwin" || process.platform === "linux" ? process.platform : void 0, t = process.arch === "arm64" || process.arch === "x64" ? process.arch : void 0;
241
245
  return e && t ? `@incajs/host-${e}-${t}` : void 0;
242
246
  }
243
247
  function pe() {
244
- let e = M();
248
+ let e = N();
245
249
  if (e) try {
246
250
  return v(import.meta.url).resolve(`${e}/bin/inca-host`);
247
251
  } catch {
248
252
  return;
249
253
  }
250
254
  }
251
- function N() {
252
- let e = process.env[j];
255
+ function P() {
256
+ let e = process.env[M];
253
257
  if (e) return e;
254
258
  let t = pe();
255
259
  if (t) return t;
256
- let n = M();
257
- throw new S("ERR_INCA_HOST_BIN_UNRESOLVED", `no inca-host binary found — ${n ? `no ${n} package is installed for it` : `this platform (${process.platform}/${process.arch}) has no published package`}, and ${j} isn't set to one`);
260
+ let n = N();
261
+ throw new C("ERR_INCA_HOST_BIN_UNRESOLVED", `no inca-host binary found — ${n ? `no ${n} package is installed for it` : `this platform (${process.platform}/${process.arch}) has no published package`}, and ${M} isn't set to one`);
258
262
  }
259
263
  //#endregion
260
264
  //#region src/dev-client/hostError.mts
261
- var P = class extends Error {
265
+ var F = class extends Error {
262
266
  code;
263
267
  hostStack;
264
268
  constructor(e, t, n = null) {
265
269
  super(e), this.code = t, this.hostStack = n, this.name = "HostError";
266
270
  }
267
271
  };
268
- function F(e) {
272
+ function me(e) {
269
273
  return typeof e == "object" && !!e && e.jsonrpc === "2.0";
270
274
  }
271
275
  //#endregion
@@ -282,7 +286,7 @@ var I = (e) => {
282
286
  this.#e = e;
283
287
  }
284
288
  async start() {
285
- let e = this.#e.hostBin ?? N(), t = y(e, ["--dev", this.#e.entryFile], { stdio: [
289
+ let e = this.#e.hostBin ?? P(), t = y(e, ["--dev", this.#e.entryFile], { stdio: [
286
290
  "pipe",
287
291
  "pipe",
288
292
  "pipe"
@@ -307,7 +311,7 @@ var I = (e) => {
307
311
  t(`[stray stdout] ${e}`);
308
312
  return;
309
313
  }
310
- if (!F(n)) {
314
+ if (!me(n)) {
311
315
  t(`[stray stdout] ${e}`);
312
316
  return;
313
317
  }
@@ -316,7 +320,7 @@ var I = (e) => {
316
320
  return;
317
321
  }
318
322
  let r = this.#r.get(n.id);
319
- r && (this.#r.delete(n.id), "error" in n ? r.reject(new P(n.error.message, n.error.code, n.error.data?.stack ?? null)) : r.resolve(n.result));
323
+ r && (this.#r.delete(n.id), "error" in n ? r.reject(new F(n.error.message, n.error.code, n.error.data?.stack ?? null)) : r.resolve(n.result));
320
324
  }
321
325
  #o(e, t, n) {
322
326
  switch (e) {
@@ -343,21 +347,28 @@ var I = (e) => {
343
347
  let t = b(e, "exit");
344
348
  e.kill(), await t;
345
349
  }
346
- async call(e, t) {
347
- let n = this.#t;
348
- if (!n) throw Error("HostClient.start() has not been called");
349
- let r = this.#n++, i = JSON.stringify({
350
+ async call(e, t, n) {
351
+ let r = this.#t;
352
+ if (!r) throw Error("HostClient.start() has not been called");
353
+ let i = this.#n++, a = JSON.stringify({
350
354
  jsonrpc: "2.0",
351
- id: r,
355
+ id: i,
352
356
  method: e,
353
357
  params: t
354
358
  });
355
- return new Promise((e, t) => {
356
- this.#r.set(r, {
357
- resolve: e,
358
- reject: t
359
- }), n.stdin.write(`${i}\n`, (e) => {
360
- e && (this.#r.delete(r), t(e));
359
+ return new Promise((t, o) => {
360
+ let s = n === void 0 ? void 0 : setTimeout(() => {
361
+ this.#r.delete(i), o(/* @__PURE__ */ Error(`${e} timed out after ${String(n)}ms`));
362
+ }, n);
363
+ this.#r.set(i, {
364
+ resolve: (e) => {
365
+ clearTimeout(s), t(e);
366
+ },
367
+ reject: (e) => {
368
+ clearTimeout(s), o(e);
369
+ }
370
+ }), r.stdin.write(`${a}\n`, (e) => {
371
+ e && (clearTimeout(s), this.#r.delete(i), o(e));
361
372
  });
362
373
  });
363
374
  }
@@ -366,7 +377,7 @@ var I = (e) => {
366
377
  if (!t || t.exitCode !== null || t.signalCode !== null) return;
367
378
  this.#i = !0;
368
379
  let n = b(t, "exit");
369
- this.call("shutdown").catch(() => {}), await Promise.race([n.then(() => "exited"), ee(e).then(() => "timeout")]) === "timeout" && (t.kill(), await n);
380
+ this.call("shutdown").catch(() => {}), await Promise.race([n.then(() => "exited"), S(e).then(() => "timeout")]) === "timeout" && (t.kill(), await n);
370
381
  }
371
382
  }, R = "[inca]", z = new Intl.DateTimeFormat(void 0, {
372
383
  hour: "numeric",
@@ -384,16 +395,16 @@ function H(e) {
384
395
  let t = e.code;
385
396
  return typeof t == "string" ? t : null;
386
397
  }
387
- function me(e) {
398
+ function he(e) {
388
399
  return /\bERR_INCA_[A-Z0-9_]+/.exec(e)?.[0] ?? null;
389
400
  }
390
- function he(e) {
401
+ function ge(e) {
391
402
  let t = e.stack;
392
403
  if (!t) return null;
393
404
  for (let n of [`${e.name}: ${e.message}`, e.message]) if (t.startsWith(n)) return t.slice(n.length).replace(/^\r?\n/, "") || null;
394
405
  return t;
395
406
  }
396
- function ge(e) {
407
+ function _e(e) {
397
408
  let t = /^(?:\w*Error: )?(ERR_INCA_[A-Z0-9_]+): /.exec(e);
398
409
  return t ? {
399
410
  message: e.slice(t[0].length),
@@ -406,14 +417,14 @@ function ge(e) {
406
417
  };
407
418
  }
408
419
  function U(e) {
409
- return e instanceof P ? {
420
+ return e instanceof F ? {
410
421
  message: e.message,
411
422
  stack: e.hostStack,
412
423
  code: H(e)
413
424
  } : e instanceof Error ? {
414
425
  message: e.message,
415
- stack: he(e),
416
- code: H(e) ?? me(e.message)
426
+ stack: ge(e),
427
+ code: H(e) ?? he(e.message)
417
428
  } : {
418
429
  message: String(e),
419
430
  stack: null,
@@ -426,38 +437,33 @@ function W(e, t, n, r = {}) {
426
437
  }
427
438
  //#endregion
428
439
  //#region src/adapter/vite/watch.mts
429
- async function _e({ onBuild: e, onError: t, stdout: n = process.stdout, stderr: r = process.stderr, quiet: i = !1, ...o }) {
430
- let { outDir: s } = o, c, l = await g(A({
431
- ...o,
440
+ async function ve({ onBuild: e, onError: t, stdout: n = process.stdout, stderr: r = process.stderr, quiet: i = !1, ...a }) {
441
+ let { outDir: o } = a, s, c = await g(j({
442
+ ...a,
432
443
  watch: !0,
433
444
  stdout: n,
434
445
  stderr: r,
435
446
  quiet: i,
436
447
  onOutput: (t) => {
437
- e({
438
- outDir: s,
439
- entryFile: a.join(s, t.entryFile),
440
- files: t.files,
441
- changed: c
442
- }), c = void 0;
448
+ e(A(o, t, s)), s = void 0;
443
449
  }
444
450
  }));
445
- return l.on("change", (e) => {
446
- c ??= {
451
+ return c.on("change", (e) => {
452
+ s ??= {
447
453
  file: e,
448
454
  at: Date.now()
449
455
  };
450
- }), l.on("event", (e) => {
456
+ }), c.on("event", (e) => {
451
457
  if (e.code !== "ERROR") return;
452
- c = void 0;
458
+ s = void 0;
453
459
  let { errors: n } = e.error;
454
- t(ge(n?.[0]?.message ?? e.error.message));
455
- }), { close: () => l.close() };
460
+ t(_e(n?.[0]?.message ?? e.error.message));
461
+ }), { close: () => c.close() };
456
462
  }
457
463
  //#endregion
458
464
  //#region src/defaultBundler.mts
459
465
  var G = {
460
- watch: _e,
466
+ watch: ve,
461
467
  build: fe
462
468
  };
463
469
  //#endregion
@@ -466,10 +472,10 @@ async function K(e) {
466
472
  let t = a.join(e, "src/main.mts");
467
473
  if (o(t)) return t;
468
474
  let n = a.join(e, "src/App.vue");
469
- if (o(n)) return ve(n, e);
470
- throw new S("ERR_INCA_ENTRY_NOT_FOUND", `no app entry found — expected ${t} or ${n}`);
475
+ if (o(n)) return ye(n, e);
476
+ throw new C("ERR_INCA_ENTRY_NOT_FOUND", `no app entry found — expected ${t} or ${n}`);
471
477
  }
472
- async function ve(e, t) {
478
+ async function ye(e, t) {
473
479
  let n = a.join(t, "node_modules/.inca");
474
480
  await u(n, { recursive: !0 });
475
481
  let r = a.join(n, "entry.mts"), i = JSON.stringify(e.split(a.sep).join("/"));
@@ -478,7 +484,7 @@ async function ve(e, t) {
478
484
  //#endregion
479
485
  //#region src/build.mts
480
486
  async function q(e = {}) {
481
- let t = e.cwd ?? process.cwd(), n = e.config ?? await T(t), r = n.outDir, i = e.bundler ?? G, a = e.entry ?? n.entry ?? await K(t), o = e.runtimeConfig ?? await O(t);
487
+ let t = e.cwd ?? process.cwd(), n = e.config ?? await E(t), r = n.outDir, i = e.bundler ?? G, a = e.entry ?? n.entry ?? await K(t), o = e.runtimeConfig ?? await k(t);
482
488
  return i.build({
483
489
  entry: a,
484
490
  outDir: r,
@@ -489,41 +495,41 @@ async function q(e = {}) {
489
495
  }
490
496
  //#endregion
491
497
  //#region src/dev-lock.mts
492
- function J(e) {
498
+ function be(e) {
493
499
  return a.join(e, "node_modules/.inca/dev.pid");
494
500
  }
495
- function ye(e) {
501
+ function xe(e) {
496
502
  try {
497
503
  return process.kill(e, 0), !0;
498
504
  } catch (e) {
499
505
  return e.code === "EPERM";
500
506
  }
501
507
  }
502
- async function be(e) {
503
- let t = J(e), n = Number.parseInt(await d(t, "utf8").catch(() => ""), 10);
504
- if (Number.isInteger(n) && ye(n)) throw new S("ERR_INCA_DEV_RUNNING", `inca dev is already running for this app (pid ${String(n)})`);
508
+ async function Se(e) {
509
+ let t = be(e), n = Number.parseInt(await d(t, "utf8").catch(() => ""), 10);
510
+ if (Number.isInteger(n) && xe(n)) throw new C("ERR_INCA_DEV_RUNNING", `inca dev is already running for this app (pid ${String(n)})`);
505
511
  return await u(a.dirname(t), { recursive: !0 }), await m(t, String(process.pid)), () => p(t, { force: !0 });
506
512
  }
507
513
  //#endregion
508
514
  //#region src/plist.mts
509
- function Y(e) {
515
+ function J(e) {
510
516
  return e.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
511
517
  }
512
- function xe(e) {
513
- return typeof e == "boolean" ? e ? "<true/>" : "<false/>" : `<string>${Y(e)}</string>`;
518
+ function Ce(e) {
519
+ return typeof e == "boolean" ? e ? "<true/>" : "<false/>" : `<string>${J(e)}</string>`;
514
520
  }
515
- function Se(e) {
521
+ function we(e) {
516
522
  return `<?xml version="1.0" encoding="UTF-8"?>
517
523
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
518
524
  <plist version="1.0">
519
525
  <dict>
520
- ${Object.entries(e).map(([e, t]) => `\t<key>${Y(e)}</key>\n\t${xe(t)}`).join("\n")}\n</dict>
526
+ ${Object.entries(e).map(([e, t]) => `\t<key>${J(e)}</key>\n\t${Ce(t)}`).join("\n")}\n</dict>
521
527
  </plist>
522
528
  `;
523
529
  }
524
530
  //#endregion
525
531
  //#region src/macos-app.mts
526
- async function X(e) {
532
+ async function Y(e) {
527
533
  let { appPath: t, metadata: n, hostBin: r } = e;
528
534
  await p(t, {
529
535
  recursive: !0,
@@ -548,7 +554,7 @@ async function X(e) {
548
554
  let e = a.basename(n.icon);
549
555
  await c(n.icon, a.join(d, e)), h.CFBundleIconFile = e;
550
556
  }
551
- return await m(a.join(i, "Info.plist"), Se(h)), await m(a.join(i, "PkgInfo"), "APPL????"), {
557
+ return await m(a.join(i, "Info.plist"), we(h)), await m(a.join(i, "PkgInfo"), "APPL????"), {
552
558
  appPath: t,
553
559
  executablePath: f,
554
560
  resourcesDir: d
@@ -556,30 +562,30 @@ async function X(e) {
556
562
  }
557
563
  //#endregion
558
564
  //#region src/dev.mts
559
- var Z = { timestamp: !0 }, Ce = ["ERR_INCA_PACKAGE_JSON_NOT_FOUND", "ERR_INCA_PRODUCT_NAME_MISSING"];
560
- async function we(e, t) {
565
+ var X = { timestamp: !0 }, Te = 1e4, Ee = ["ERR_INCA_PACKAGE_JSON_NOT_FOUND", "ERR_INCA_PRODUCT_NAME_MISSING"];
566
+ async function De(e, t) {
561
567
  try {
562
- return await E(e);
568
+ return await D(e);
563
569
  } catch (e) {
564
- if (!(e instanceof S) || !Ce.includes(e.code)) throw e;
565
- V(t, `running unnamed — ${e.message}`, Z);
570
+ if (!(e instanceof C) || !Ee.includes(e.code)) throw e;
571
+ V(t, `running unnamed — ${e.message}`, X);
566
572
  return;
567
573
  }
568
574
  }
569
- async function Te(e, t, n, r) {
575
+ async function Oe(e, t, n, r) {
570
576
  if (process.platform === "darwin" && t) try {
571
- return (await X({
577
+ return (await Y({
572
578
  appPath: a.join(e, "node_modules/.inca", `${t.productName}.app`),
573
579
  metadata: t,
574
- hostBin: n ?? N(),
580
+ hostBin: n ?? P(),
575
581
  link: !0
576
582
  })).executablePath;
577
583
  } catch (e) {
578
- V(r, `running unbundled — ${U(e).message}`, Z);
584
+ V(r, `running unbundled — ${U(e).message}`, X);
579
585
  return;
580
586
  }
581
587
  }
582
- async function Ee(e, t) {
588
+ async function ke(e, t) {
583
589
  let n = new Set(t), r;
584
590
  try {
585
591
  r = await f(e, {
@@ -591,40 +597,43 @@ async function Ee(e, t) {
591
597
  }
592
598
  await Promise.all(r.filter((e) => e.isFile()).map((t) => a.relative(e, a.join(t.parentPath, t.name))).filter((e) => !n.has(e)).map((t) => p(a.join(e, t), { force: !0 })));
593
599
  }
594
- async function De(e) {
595
- let t = e.cwd ?? process.cwd(), n = await T(t), r = await be(t);
600
+ async function Z(e) {
601
+ let t = e.cwd ?? process.cwd(), n = await E(t), r = await Se(t);
596
602
  try {
597
- let r = n.outDir, i = e.bundler ?? G, o = e.stdout ?? process.stdout, s = e.stderr ?? process.stderr, c = e.entry ?? n.entry ?? await K(t), l = await we(t, o), u = l ? D(l) : await O(t), d = await Te(t, l, e.hostBin, o) ?? e.hostBin, f, p = !1, m = !1, g = Promise.resolve(), _ = () => {}, v = new Promise((e) => {
603
+ let r = n.outDir, i = e.bundler ?? G, o = e.stdout ?? process.stdout, s = e.stderr ?? process.stderr, c = e.entry ?? n.entry ?? await K(t), l = await De(t, o), u = l ? O(l) : await k(t), d = await Oe(t, l, e.hostBin, o) ?? e.hostBin, f, p = !1, m = !1, g = Promise.resolve(), _ = () => {}, v = new Promise((e) => {
598
604
  _ = e;
599
605
  });
600
606
  async function y() {
601
607
  try {
602
- return await f?.call("reload"), !0;
608
+ return await f?.call("reload", void 0, Te), !0;
603
609
  } catch (e) {
604
- return W(s, "reload failed", U(e), Z), !1;
610
+ return W(s, "reload failed", U(e), X), !1;
605
611
  }
606
612
  }
607
613
  async function b(e) {
608
- if (await Ee(e.outDir, e.files), !f) {
609
- let t = new L({
610
- entryFile: e.entryFile,
611
- hostBin: d,
612
- onStderr: (e) => s.write(e),
613
- onReady: () => {
614
- p = !0, V(o, "ready", Z), m && (m = !1, y());
615
- },
616
- onAppError: (e) => W(s, "app error", e, Z),
617
- onExit: () => {
618
- V(o, "host exited — stopping", Z), _();
619
- }
620
- });
621
- try {
622
- await t.start();
623
- } catch (e) {
624
- W(s, "failed to start inca-host", U(e), Z);
625
- return;
614
+ let t = new L({
615
+ entryFile: e,
616
+ hostBin: d,
617
+ onStderr: (e) => s.write(e),
618
+ onReady: () => {
619
+ p = !0, V(o, "ready", X), m && (m = !1, y());
620
+ },
621
+ onAppError: (e) => W(s, "app error", e, X),
622
+ onExit: () => {
623
+ V(o, "host exited — stopping", X), _();
626
624
  }
627
- f = t;
625
+ });
626
+ try {
627
+ await t.start();
628
+ } catch (e) {
629
+ W(s, "failed to start inca-host", U(e), X);
630
+ return;
631
+ }
632
+ f = t;
633
+ }
634
+ async function x(e) {
635
+ if (await ke(e.outDir, e.files), !f) {
636
+ await b(e.entryFile);
628
637
  return;
629
638
  }
630
639
  if (!p) {
@@ -633,10 +642,10 @@ async function De(e) {
633
642
  }
634
643
  if (await y() && e.changed) {
635
644
  let n = h("dim", a.relative(t, e.changed.file), { stream: o }), r = Date.now() - e.changed.at;
636
- V(o, `${h("green", "reload")} ${n} (${r}ms)`, Z);
645
+ V(o, `${h("green", "reload")} ${n} (${r}ms)`, X);
637
646
  }
638
647
  }
639
- let x = await i.watch({
648
+ let S = await i.watch({
640
649
  entry: c,
641
650
  outDir: r,
642
651
  runtimeConfig: u,
@@ -644,23 +653,23 @@ async function De(e) {
644
653
  stdout: o,
645
654
  stderr: s,
646
655
  onBuild: (e) => {
647
- g = g.then(() => b(e));
656
+ g = g.then(() => x(e));
648
657
  },
649
658
  onError: (e) => {
650
- W(s, "build failed", e, Z);
659
+ W(s, "build failed", e, X);
651
660
  }
652
661
  });
653
- e.signal.aborted ? _() : e.signal.addEventListener("abort", () => _(), { once: !0 }), await v, await g, await f?.stop(), await x.close();
662
+ e.signal.aborted ? _() : e.signal.addEventListener("abort", () => _(), { once: !0 }), await v, await g, await f?.stop(), await S.close();
654
663
  } finally {
655
664
  await r();
656
665
  }
657
666
  }
658
667
  //#endregion
659
668
  //#region src/package.mts
660
- function Oe() {
669
+ function Ae() {
661
670
  if (process.platform === "darwin") return "macos";
662
671
  if (process.platform === "linux") return "linux";
663
- throw new S("ERR_INCA_PLATFORM_UNSUPPORTED", `inca package doesn't support ${process.platform} yet`);
672
+ throw new C("ERR_INCA_PLATFORM_UNSUPPORTED", `inca package doesn't support ${process.platform} yet`);
664
673
  }
665
674
  async function Q(e, t) {
666
675
  await Promise.all(e.files.map(async (n) => {
@@ -668,15 +677,15 @@ async function Q(e, t) {
668
677
  await u(a.dirname(r), { recursive: !0 }), await c(a.join(e.outDir, n), r);
669
678
  }));
670
679
  }
671
- async function ke({ metadata: e, output: t, hostBin: n }) {
672
- let { appPath: r, resourcesDir: i } = await X({
680
+ async function je({ metadata: e, output: t, hostBin: n }) {
681
+ let { appPath: r, resourcesDir: i } = await Y({
673
682
  appPath: a.join(t.outDir, `${e.productName}.app`),
674
683
  metadata: e,
675
684
  hostBin: n
676
685
  });
677
686
  return await Q(t, i), r;
678
687
  }
679
- async function Ae({ metadata: t, output: n, hostBin: r }) {
688
+ async function Me({ metadata: t, output: n, hostBin: r }) {
680
689
  let i = e(t.productName), o = a.join(n.outDir, i);
681
690
  await p(o, {
682
691
  recursive: !0,
@@ -685,33 +694,33 @@ async function Ae({ metadata: t, output: n, hostBin: r }) {
685
694
  let l = a.join(o, i);
686
695
  return await c(r, l), await s(l, 493), await Q(n, o), o;
687
696
  }
688
- async function je(e = {}) {
689
- let t = e.cwd ?? process.cwd(), n = e.stdout ?? process.stdout, r = e.target ?? Oe(), i = await E(t);
697
+ async function Ne(e = {}) {
698
+ let t = e.cwd ?? process.cwd(), n = e.stdout ?? process.stdout, r = e.target ?? Ae(), i = await D(t);
690
699
  i.usedPackageJsonKey && V(n, "the \"inca\" key in package.json is deprecated — move these settings to inca.config.ts"), i.identifierIsDefault && V(n, `no "identifier" set in inca.config.ts — using generated identifier ${i.identifier}`);
691
700
  let a = await q({
692
701
  cwd: t,
693
702
  entry: e.entry,
694
703
  config: i,
695
- runtimeConfig: D(i),
704
+ runtimeConfig: O(i),
696
705
  bundler: e.bundler,
697
706
  stdout: n,
698
707
  stderr: e.stderr
699
- }), s = e.hostBin ?? N();
700
- if (!o(s)) throw new S("ERR_INCA_HOST_BIN_NOT_FOUND", `no host binary at ${s} — check that it was built and is executable`);
708
+ }), s = e.hostBin ?? P();
709
+ if (!o(s)) throw new C("ERR_INCA_HOST_BIN_NOT_FOUND", `no host binary at ${s} — check that it was built and is executable`);
701
710
  let c = {
702
711
  metadata: i,
703
712
  output: a,
704
713
  hostBin: s
705
714
  };
706
- return { appPath: r === "macos" ? await ke(c) : await Ae(c) };
715
+ return { appPath: r === "macos" ? await je(c) : await Me(c) };
707
716
  }
708
717
  //#endregion
709
718
  //#region src/cli.mts
710
- var Me = "Usage: inca <dev|build|package>";
719
+ var Pe = "Usage: inca <dev|build|package>";
711
720
  function $(e) {
712
721
  return a.relative(process.cwd(), e);
713
722
  }
714
- async function Ne(e = process.argv) {
723
+ async function Fe(e = process.argv) {
715
724
  let t = e[2];
716
725
  if (t === "build") {
717
726
  try {
@@ -724,7 +733,7 @@ async function Ne(e = process.argv) {
724
733
  }
725
734
  if (t === "package") {
726
735
  try {
727
- let { appPath: e } = await je();
736
+ let { appPath: e } = await Ne();
728
737
  V(process.stdout, `packaged ${$(e)}`);
729
738
  } catch (e) {
730
739
  W(process.stderr, "package failed", U(e)), process.exitCode = 1;
@@ -732,7 +741,7 @@ async function Ne(e = process.argv) {
732
741
  return;
733
742
  }
734
743
  if (t !== "dev") {
735
- process.stderr.write(`${Me}\n`), process.exitCode = 1;
744
+ process.stderr.write(`${Pe}\n`), process.exitCode = 1;
736
745
  return;
737
746
  }
738
747
  let n = new AbortController(), r = () => {
@@ -740,10 +749,10 @@ async function Ne(e = process.argv) {
740
749
  };
741
750
  process.on("SIGINT", r), process.on("SIGTERM", r);
742
751
  try {
743
- await De({ signal: n.signal });
752
+ await Z({ signal: n.signal });
744
753
  } catch (e) {
745
754
  W(process.stderr, "dev failed", U(e), { timestamp: !0 }), process.exitCode = 1;
746
755
  }
747
756
  }
748
757
  //#endregion
749
- export { Ne as run };
758
+ export { Fe as run };
@@ -44,8 +44,14 @@ export declare class HostClient {
44
44
  * binary doesn't exist).
45
45
  */
46
46
  start(): Promise<void>;
47
- /** Sends a request and resolves with its result once the host answers. */
48
- call(method: string, params?: unknown): Promise<unknown>;
47
+ /**
48
+ * Sends a request and resolves with its result once the host answers.
49
+ * With `timeoutMs`, rejects once that much time passes with no answer —
50
+ * the host answers on the same thread that runs the app's JS, so a
51
+ * wedged app leaves a call pending forever otherwise (PROTOCOL.md:
52
+ * "every response a client waits for needs a deadline").
53
+ */
54
+ call(method: string, params?: unknown, timeoutMs?: number): Promise<unknown>;
49
55
  /**
50
56
  * Asks the host to `shutdown` and waits for the child to actually exit —
51
57
  * that exit is the real acknowledgement, not the response. Kills it once
package/dist/index.d.mts CHANGED
@@ -1,2 +1 @@
1
- export type { BuildOptions, BuildOutput, Bundler, BundlerOptions, Watcher, } from './adapter/types.mts';
2
1
  export type { ResolvedAppConfig } from './config/loader.mts';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@incajs/cli",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Dev server, bundler, and packager for Incarnative.js apps.",
5
5
  "keywords": [
6
6
  "bundler",
@@ -68,9 +68,9 @@
68
68
  }
69
69
  },
70
70
  "optionalDependencies": {
71
- "@incajs/host-darwin-arm64": "0.0.4",
72
- "@incajs/host-linux-arm64": "0.0.4",
73
- "@incajs/host-linux-x64": "0.0.4"
71
+ "@incajs/host-darwin-arm64": "0.0.5",
72
+ "@incajs/host-linux-arm64": "0.0.5",
73
+ "@incajs/host-linux-x64": "0.0.5"
74
74
  },
75
75
  "engines": {
76
76
  "node": ">=22.18"