electron-incremental-update 1.0.1 → 1.0.3

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
@@ -42,7 +42,7 @@ electron
42
42
  │ └── index.ts
43
43
  ├── preload
44
44
  │ └── index.ts
45
- └── native // possible native modules
45
+ └── native // <- possible native modules
46
46
  └── index.ts
47
47
  src
48
48
  └── ...
@@ -158,7 +158,7 @@ module.exports = {
158
158
 
159
159
  ## Usage
160
160
 
161
- ### use in main process
161
+ ### Use in main process
162
162
 
163
163
  To use electron's `net` module for updating, the `checkUpdate` and `download` functions must be called after the app is ready by default.
164
164
 
@@ -210,7 +210,7 @@ export default startupWithUpdater((updater) => {
210
210
  })
211
211
  ```
212
212
 
213
- ### use native modules
213
+ ### Use native modules
214
214
 
215
215
  All the **native modules** should be set as `dependency` in `package.json`. `electron-rebuild` only check dependencies inside `dependency` field.
216
216
 
@@ -296,6 +296,240 @@ module.exports = {
296
296
  }
297
297
  ```
298
298
 
299
+ ### Types
300
+
301
+ ```ts
302
+ export type ElectronWithUpdaterOptions = {
303
+ /**
304
+ * whether is in build mode
305
+ * ```ts
306
+ * export default defineConfig(({ command }) => {
307
+ * const isBuild = command === 'build'
308
+ * })
309
+ * ```
310
+ */
311
+ isBuild: boolean
312
+ /**
313
+ * name, version and main in `package.json`
314
+ * ```ts
315
+ * import pkg from './package.json'
316
+ * ```
317
+ */
318
+ pkg: PKG
319
+ /**
320
+ * main options
321
+ */
322
+ main: MakeRequiredAndReplaceKey<ElectronSimpleOptions['main'], 'entry', 'files'>
323
+ /**
324
+ * preload options
325
+ */
326
+ preload: MakeRequiredAndReplaceKey<Exclude<ElectronSimpleOptions['preload'], undefined>, 'input', 'files'>
327
+ /**
328
+ * updater options
329
+ */
330
+ updater?: ElectronUpdaterOptions
331
+ /**
332
+ * use NotBundle() plugin in main
333
+ * @default true
334
+ */
335
+ useNotBundle?: boolean
336
+ /**
337
+ * Whether to log parsed options
338
+ */
339
+ logParsedOptions?: boolean
340
+ }
341
+
342
+ export type BuildEntryOption = {
343
+ /**
344
+ * whether to minify
345
+ * @default isBuild
346
+ */
347
+ minify?: boolean
348
+ /**
349
+ * whether to generate sourcemap
350
+ * @default isBuild
351
+ */
352
+ sourcemap?: boolean
353
+ /**
354
+ * path to app entry output file
355
+ * @default 'dist-entry'
356
+ */
357
+ entryOutputDirPath?: string
358
+ /**
359
+ * path to app entry file
360
+ * @default 'electron/entry.ts'
361
+ */
362
+ appEntryPath?: string
363
+ /**
364
+ * esbuild path map of native modules in entry directory
365
+ *
366
+ * @default {}
367
+ * @example
368
+ * { db: './electron/native/db.ts' }
369
+ */
370
+ nativeModuleEntryMap?: Record<string, string>
371
+ /**
372
+ * custom options for esbuild
373
+ * ```ts
374
+ * // default options
375
+ * const options = {
376
+ * entryPoints: {
377
+ * entry: appEntryPath,
378
+ * ...moduleEntryMap,
379
+ * },
380
+ * bundle: true,
381
+ * platform: 'node',
382
+ * outdir: entryOutputDirPath,
383
+ * minify,
384
+ * sourcemap,
385
+ * entryNames: '[dir]/[name]',
386
+ * assetNames: '[dir]/[name]',
387
+ * external: ['electron', 'original-fs'],
388
+ * loader: {
389
+ * '.node': 'empty',
390
+ * },
391
+ * }
392
+ * ```
393
+ */
394
+ overrideEsbuildOptions?: BuildOptions
395
+ /**
396
+ * resolve extra files on startup, such as `.node`
397
+ * @remark won't trigger will reload
398
+ */
399
+ postBuild?: (args: {
400
+ /**
401
+ * get path from `entryOutputDirPath`
402
+ */
403
+ getPathFromEntryOutputDir: (...paths: string[]) => string
404
+ /**
405
+ * copy file to `entryOutputDirPath`
406
+ *
407
+ * if `to` absent, set to `basename(from)`
408
+ *
409
+ * if `skipIfExist` absent, skip copy if `to` exist
410
+ */
411
+ existsAndCopyToEntryOutputDir: (options: {
412
+ from: string
413
+ to?: string
414
+ /**
415
+ * skip copy if `to` exist
416
+ * @default true
417
+ */
418
+ skipIfExist?: boolean
419
+ }) => void
420
+ }) => Promisable<void>
421
+ }
422
+
423
+ export type GeneratorOverrideFunctions = {
424
+ /**
425
+ * custom signature generate function
426
+ * @param buffer file buffer
427
+ * @param privateKey private key
428
+ * @param cert certificate string, **EOL must be '\n'**
429
+ * @param version current version
430
+ */
431
+ generateSignature?: (buffer: Buffer, privateKey: string, cert: string, version: string) => string | Promise<string>
432
+ /**
433
+ * custom generate version json function
434
+ * @param existingJson The existing JSON object.
435
+ * @param buffer file buffer
436
+ * @param signature generated signature
437
+ * @param version current version
438
+ * @param minVersion The minimum version
439
+ * @returns The updated version json
440
+ */
441
+ generateVersionJson?: (existingJson: UpdateJSON, buffer: Buffer, signature: string, version: string, minVersion: string) => UpdateJSON | Promise<UpdateJSON>
442
+ }
443
+
444
+ export type ElectronUpdaterOptions = {
445
+ /**
446
+ * mini version of entry
447
+ * @default '0.0.0'
448
+ */
449
+ minimumVersion?: string
450
+ /**
451
+ * config for entry (app.asar)
452
+ */
453
+ entry?: BuildEntryOption
454
+ /**
455
+ * paths config
456
+ */
457
+ paths?: {
458
+ /**
459
+ * Path to asar file
460
+ * @default `release/${app.name}.asar`
461
+ */
462
+ asarOutputPath?: string
463
+ /**
464
+ * Path to version info output, content is {@link UpdateJSON}
465
+ * @default `version.json`
466
+ */
467
+ versionPath?: string
468
+ /**
469
+ * Path to gzipped asar file
470
+ * @default `release/${app.name}-${version}.asar.gz`
471
+ */
472
+ gzipPath?: string
473
+ /**
474
+ * Path to electron build output
475
+ * @default `dist-electron`
476
+ */
477
+ electronDistPath?: string
478
+ /**
479
+ * Path to renderer build output
480
+ * @default `dist`
481
+ */
482
+ rendererDistPath?: string
483
+ }
484
+ /**
485
+ * signature config
486
+ */
487
+ keys?: {
488
+ /**
489
+ * path to the pem file that contains private key
490
+ * if not ended with .pem, it will be appended
491
+ *
492
+ * **if `UPDATER_PK` is set, will read it instead of read from `privateKeyPath`**
493
+ * @default 'keys/private.pem'
494
+ */
495
+ privateKeyPath?: string
496
+ /**
497
+ * path to the pem file that contains public key
498
+ * if not ended with .pem, it will be appended
499
+ *
500
+ * **if `UPDATER_CERT` is set, will read it instead of read from `certPath`**
501
+ * @default 'keys/cert.pem'
502
+ */
503
+ certPath?: string
504
+ /**
505
+ * length of the key
506
+ * @default 2048
507
+ */
508
+ keyLength?: number
509
+ /**
510
+ * X509 certificate info
511
+ *
512
+ * only generate simple **self-signed** certificate **without extensions**
513
+ */
514
+ certInfo?: {
515
+ /**
516
+ * the subject of the certificate
517
+ *
518
+ * @default { commonName: `${app.name}`, organizationName: `org.${app.name}` }
519
+ */
520
+ subject?: DistinguishedName
521
+ /**
522
+ * expire days of the certificate
523
+ *
524
+ * @default 3650
525
+ */
526
+ days?: number
527
+ }
528
+ overrideGenerator?: GeneratorOverrideFunctions
529
+ }
530
+ }
531
+ ```
532
+
299
533
  ## License
300
534
 
301
535
  MIT
package/dist/vite.d.mts CHANGED
@@ -1,6 +1,7 @@
1
+ import * as vite from 'vite';
1
2
  import { Plugin } from 'vite';
2
3
  import { ElectronSimpleOptions } from 'vite-plugin-electron/simple';
3
- import { Promisable, Prettify } from '@subframe7536/type-utils';
4
+ import { Promisable } from '@subframe7536/type-utils';
4
5
  import { BuildOptions } from 'esbuild';
5
6
  import { a as UpdateJSON } from './noDep-TvZoKVF8.mjs';
6
7
 
@@ -27,22 +28,22 @@ type BuildEntryOption = {
27
28
  * whether to minify
28
29
  * @default isBuild
29
30
  */
30
- minify: boolean;
31
+ minify?: boolean;
31
32
  /**
32
- * Whether to generate sourcemap
33
+ * whether to generate sourcemap
33
34
  * @default isBuild
34
35
  */
35
- sourcemap: boolean;
36
+ sourcemap?: boolean;
36
37
  /**
37
38
  * path to app entry output file
38
39
  * @default 'dist-entry'
39
40
  */
40
- entryOutputDirPath: string;
41
+ entryOutputDirPath?: string;
41
42
  /**
42
43
  * path to app entry file
43
44
  * @default 'electron/entry.ts'
44
45
  */
45
- appEntryPath: string;
46
+ appEntryPath?: string;
46
47
  /**
47
48
  * esbuild path map of native modules in entry directory
48
49
  *
@@ -76,7 +77,8 @@ type BuildEntryOption = {
76
77
  */
77
78
  overrideEsbuildOptions?: BuildOptions;
78
79
  /**
79
- * resolve extra files, such as `.node`
80
+ * resolve extra files on startup, such as `.node`
81
+ * @remark won't trigger will reload
80
82
  */
81
83
  postBuild?: (args: {
82
84
  /**
@@ -130,7 +132,7 @@ type ElectronUpdaterOptions = {
130
132
  /**
131
133
  * config for entry (app.asar)
132
134
  */
133
- entry?: Partial<BuildEntryOption>;
135
+ entry?: BuildEntryOption;
134
136
  /**
135
137
  * paths config
136
138
  */
@@ -252,11 +254,11 @@ type ElectronWithUpdaterOptions = {
252
254
  /**
253
255
  * main options
254
256
  */
255
- main: Prettify<MakeRequiredAndReplaceKey<ElectronSimpleOptions['main'], 'entry', 'files'>>;
257
+ main: MakeRequiredAndReplaceKey<ElectronSimpleOptions['main'], 'entry', 'files'>;
256
258
  /**
257
259
  * preload options
258
260
  */
259
- preload: Prettify<MakeRequiredAndReplaceKey<Exclude<ElectronSimpleOptions['preload'], undefined>, 'input', 'files'>>;
261
+ preload: MakeRequiredAndReplaceKey<Exclude<ElectronSimpleOptions['preload'], undefined>, 'input', 'files'>;
260
262
  /**
261
263
  * updater options
262
264
  */
@@ -271,6 +273,7 @@ type ElectronWithUpdaterOptions = {
271
273
  */
272
274
  logParsedOptions?: boolean;
273
275
  };
276
+ declare const log: vite.Logger;
274
277
  /**
275
278
  * build options for `vite-plugin-electron/simple`
276
279
  * - integrate with updater
@@ -323,4 +326,4 @@ type ElectronWithUpdaterOptions = {
323
326
  */
324
327
  declare function electronWithUpdater(options: ElectronWithUpdaterOptions): (Plugin<any> | Promise<Plugin<any>[]> | undefined)[];
325
328
 
326
- export { type ElectronWithUpdaterOptions, debugStartup, electronWithUpdater };
329
+ export { type ElectronWithUpdaterOptions, debugStartup, electronWithUpdater, log };
package/dist/vite.d.ts CHANGED
@@ -1,6 +1,7 @@
1
+ import * as vite from 'vite';
1
2
  import { Plugin } from 'vite';
2
3
  import { ElectronSimpleOptions } from 'vite-plugin-electron/simple';
3
- import { Promisable, Prettify } from '@subframe7536/type-utils';
4
+ import { Promisable } from '@subframe7536/type-utils';
4
5
  import { BuildOptions } from 'esbuild';
5
6
  import { a as UpdateJSON } from './noDep-TvZoKVF8.js';
6
7
 
@@ -27,22 +28,22 @@ type BuildEntryOption = {
27
28
  * whether to minify
28
29
  * @default isBuild
29
30
  */
30
- minify: boolean;
31
+ minify?: boolean;
31
32
  /**
32
- * Whether to generate sourcemap
33
+ * whether to generate sourcemap
33
34
  * @default isBuild
34
35
  */
35
- sourcemap: boolean;
36
+ sourcemap?: boolean;
36
37
  /**
37
38
  * path to app entry output file
38
39
  * @default 'dist-entry'
39
40
  */
40
- entryOutputDirPath: string;
41
+ entryOutputDirPath?: string;
41
42
  /**
42
43
  * path to app entry file
43
44
  * @default 'electron/entry.ts'
44
45
  */
45
- appEntryPath: string;
46
+ appEntryPath?: string;
46
47
  /**
47
48
  * esbuild path map of native modules in entry directory
48
49
  *
@@ -76,7 +77,8 @@ type BuildEntryOption = {
76
77
  */
77
78
  overrideEsbuildOptions?: BuildOptions;
78
79
  /**
79
- * resolve extra files, such as `.node`
80
+ * resolve extra files on startup, such as `.node`
81
+ * @remark won't trigger will reload
80
82
  */
81
83
  postBuild?: (args: {
82
84
  /**
@@ -130,7 +132,7 @@ type ElectronUpdaterOptions = {
130
132
  /**
131
133
  * config for entry (app.asar)
132
134
  */
133
- entry?: Partial<BuildEntryOption>;
135
+ entry?: BuildEntryOption;
134
136
  /**
135
137
  * paths config
136
138
  */
@@ -252,11 +254,11 @@ type ElectronWithUpdaterOptions = {
252
254
  /**
253
255
  * main options
254
256
  */
255
- main: Prettify<MakeRequiredAndReplaceKey<ElectronSimpleOptions['main'], 'entry', 'files'>>;
257
+ main: MakeRequiredAndReplaceKey<ElectronSimpleOptions['main'], 'entry', 'files'>;
256
258
  /**
257
259
  * preload options
258
260
  */
259
- preload: Prettify<MakeRequiredAndReplaceKey<Exclude<ElectronSimpleOptions['preload'], undefined>, 'input', 'files'>>;
261
+ preload: MakeRequiredAndReplaceKey<Exclude<ElectronSimpleOptions['preload'], undefined>, 'input', 'files'>;
260
262
  /**
261
263
  * updater options
262
264
  */
@@ -271,6 +273,7 @@ type ElectronWithUpdaterOptions = {
271
273
  */
272
274
  logParsedOptions?: boolean;
273
275
  };
276
+ declare const log: vite.Logger;
274
277
  /**
275
278
  * build options for `vite-plugin-electron/simple`
276
279
  * - integrate with updater
@@ -323,4 +326,4 @@ type ElectronWithUpdaterOptions = {
323
326
  */
324
327
  declare function electronWithUpdater(options: ElectronWithUpdaterOptions): (Plugin<any> | Promise<Plugin<any>[]> | undefined)[];
325
328
 
326
- export { type ElectronWithUpdaterOptions, debugStartup, electronWithUpdater };
329
+ export { type ElectronWithUpdaterOptions, debugStartup, electronWithUpdater, log };
package/dist/vite.js CHANGED
@@ -31,12 +31,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var vite_exports = {};
32
32
  __export(vite_exports, {
33
33
  debugStartup: () => debugStartup,
34
- electronWithUpdater: () => electronWithUpdater
34
+ electronWithUpdater: () => electronWithUpdater,
35
+ log: () => log
35
36
  });
36
37
  module.exports = __toCommonJS(vite_exports);
37
38
  var import_node_path3 = require("path");
38
39
  var import_node_fs4 = require("fs");
39
- var import_vite = require("vite");
40
+ var import_vite3 = require("vite");
40
41
  var import_simple = __toESM(require("vite-plugin-electron/simple"));
41
42
  var import_vite_plugin_electron = require("vite-plugin-electron");
42
43
  var import_plugin = require("vite-plugin-electron/plugin");
@@ -155,7 +156,7 @@ async function buildVersion({
155
156
  if (isUpdateJSON(oldVersionJson)) {
156
157
  _json = oldVersionJson;
157
158
  } else {
158
- console.warn("old version json is invalid, ignore it");
159
+ log.warn("old version json is invalid, ignore it");
159
160
  }
160
161
  } catch (error) {
161
162
  }
@@ -189,8 +190,7 @@ async function buildEntry({
189
190
  appEntryPath,
190
191
  entryOutputDirPath,
191
192
  nativeModuleEntryMap,
192
- overrideEsbuildOptions,
193
- postBuild
193
+ overrideEsbuildOptions
194
194
  }) {
195
195
  await (0, import_esbuild.build)({
196
196
  entryPoints: {
@@ -210,19 +210,6 @@ async function buildEntry({
210
210
  },
211
211
  ...overrideEsbuildOptions
212
212
  });
213
- await postBuild?.({
214
- getPathFromEntryOutputDir(...paths) {
215
- return (0, import_node_path.join)(entryOutputDirPath, ...paths);
216
- },
217
- existsAndCopyToEntryOutputDir({ from, to, skipIfExist = true }) {
218
- if ((0, import_node_fs2.existsSync)(from)) {
219
- const target = (0, import_node_path.join)(entryOutputDirPath, to ?? (0, import_node_path.basename)(from));
220
- if (!skipIfExist || !(0, import_node_fs2.existsSync)(target)) {
221
- (0, import_node_fs2.cpSync)(from, target);
222
- }
223
- }
224
- }
225
- });
226
213
  }
227
214
 
228
215
  // src/build-plugins/key.ts
@@ -275,7 +262,7 @@ function parseKeys({
275
262
  const keysDir = (0, import_node_path2.dirname)(privateKeyPath);
276
263
  !(0, import_node_fs3.existsSync)(keysDir) && (0, import_node_fs3.mkdirSync)(keysDir);
277
264
  if (!(0, import_node_fs3.existsSync)(privateKeyPath) || !(0, import_node_fs3.existsSync)(certPath)) {
278
- console.warn("no key pair found, generate new key pair");
265
+ log.warn("no key pair found, generate new key pair");
279
266
  generateKeyPair(keyLength, parseSubjects(subject), days, privateKeyPath, certPath);
280
267
  }
281
268
  const privateKey = process.env.UPDATER_PK || (0, import_node_fs3.readFileSync)(privateKeyPath, "utf-8");
@@ -298,7 +285,7 @@ function parseOptions(isBuild, pkg, options = {}) {
298
285
  appEntryPath = "electron/entry.ts",
299
286
  nativeModuleEntryMap = {},
300
287
  postBuild,
301
- overrideEsbuildOptions
288
+ overrideEsbuildOptions = {}
302
289
  } = {},
303
290
  paths: {
304
291
  asarOutputPath = `release/${pkg.name}.asar`,
@@ -336,7 +323,6 @@ function parseOptions(isBuild, pkg, options = {}) {
336
323
  entryOutputDirPath,
337
324
  appEntryPath,
338
325
  nativeModuleEntryMap,
339
- postBuild,
340
326
  overrideEsbuildOptions
341
327
  };
342
328
  const { privateKey, cert } = parseKeys({
@@ -357,7 +343,7 @@ function parseOptions(isBuild, pkg, options = {}) {
357
343
  generateSignature,
358
344
  generateVersionJson
359
345
  };
360
- return { buildAsarOption, buildEntryOption, buildVersionOption };
346
+ return { buildAsarOption, buildEntryOption, buildVersionOption, postBuild };
361
347
  }
362
348
 
363
349
  // src/vite.ts
@@ -365,7 +351,7 @@ function debugStartup(args) {
365
351
  process.env.VSCODE_DEBUG ? console.log("[startup] Electron App") : args.startup();
366
352
  }
367
353
  var id = "electron-incremental-updater";
368
- var log = (0, import_vite.createLogger)("info", { prefix: `[${id}]` });
354
+ var log = (0, import_vite3.createLogger)("info", { prefix: `[${id}]` });
369
355
  function electronWithUpdater(options) {
370
356
  const {
371
357
  isBuild,
@@ -383,18 +369,36 @@ function electronWithUpdater(options) {
383
369
  } catch (ignore) {
384
370
  }
385
371
  log.info(`remove old files`, { timestamp: true });
386
- const { buildAsarOption, buildEntryOption, buildVersionOption } = _options;
372
+ const { buildAsarOption, buildEntryOption, buildVersionOption, postBuild } = _options;
387
373
  const { entryOutputDirPath, nativeModuleEntryMap, appEntryPath } = buildEntryOption;
388
374
  const sourcemap = isBuild || !!process.env.VSCODE_DEBUG;
389
375
  const _appPath = (0, import_node_path3.join)(entryOutputDirPath, "entry.js");
390
- if ((0, import_node_path3.resolve)((0, import_vite.normalizePath)(pkg.main)) !== (0, import_node_path3.resolve)((0, import_vite.normalizePath)(_appPath))) {
391
- throw new Error(`wrong "main" field in package.json: "${pkg.main}", it should be "${(0, import_vite.normalizePath)(_appPath)}"`);
376
+ if ((0, import_node_path3.resolve)((0, import_vite3.normalizePath)(pkg.main)) !== (0, import_node_path3.resolve)((0, import_vite3.normalizePath)(_appPath))) {
377
+ throw new Error(`wrong "main" field in package.json: "${pkg.main}", it should be "${(0, import_vite3.normalizePath)(_appPath)}"`);
392
378
  }
393
379
  let isInit = false;
394
380
  const _buildEntry = async () => {
395
381
  await buildEntry(buildEntryOption);
396
382
  log.info(`build entry to '${entryOutputDirPath}'`, { timestamp: true });
397
383
  };
384
+ const _postBuild = postBuild ? async () => postBuild({
385
+ getPathFromEntryOutputDir(...paths) {
386
+ return (0, import_node_path3.join)(entryOutputDirPath, ...paths);
387
+ },
388
+ existsAndCopyToEntryOutputDir({ from, to, skipIfExist = true }) {
389
+ if ((0, import_node_fs4.existsSync)(from)) {
390
+ const target = (0, import_node_path3.join)(entryOutputDirPath, to ?? (0, import_node_path3.basename)(from));
391
+ if (!skipIfExist || !(0, import_node_fs4.existsSync)(target)) {
392
+ try {
393
+ (0, import_node_fs4.cpSync)(from, target);
394
+ } catch (ignore) {
395
+ log.warn(`copy failed: ${ignore}`);
396
+ }
397
+ }
398
+ }
399
+ }
400
+ }) : async () => {
401
+ };
398
402
  const electronPluginOptions = {
399
403
  main: {
400
404
  entry: _main.files,
@@ -402,10 +406,11 @@ function electronWithUpdater(options) {
402
406
  if (!isInit) {
403
407
  isInit = true;
404
408
  await _buildEntry();
409
+ await _postBuild();
405
410
  }
406
- _main.onstart?.(args) ?? args.startup();
411
+ _main.onstart ? _main.onstart(args) : args.startup();
407
412
  },
408
- vite: (0, import_vite.mergeConfig)(
413
+ vite: (0, import_vite3.mergeConfig)(
409
414
  {
410
415
  plugins: !isBuild && useNotBundle ? [(0, import_plugin.notBundle)()] : void 0,
411
416
  build: {
@@ -423,7 +428,7 @@ function electronWithUpdater(options) {
423
428
  preload: {
424
429
  input: _preload.files,
425
430
  onstart: _preload.onstart,
426
- vite: (0, import_vite.mergeConfig)(
431
+ vite: (0, import_vite3.mergeConfig)(
427
432
  {
428
433
  plugins: [
429
434
  {
@@ -467,14 +472,21 @@ function electronWithUpdater(options) {
467
472
  );
468
473
  let extraHmrPlugin;
469
474
  if (nativeModuleEntryMap) {
470
- const files = [...Object.values(nativeModuleEntryMap), appEntryPath].map((file) => (0, import_node_path3.resolve)((0, import_vite.normalizePath)(file)));
475
+ const files = [...Object.values(nativeModuleEntryMap), appEntryPath].map((file) => (0, import_node_path3.resolve)((0, import_vite3.normalizePath)(file)));
471
476
  extraHmrPlugin = {
472
477
  name: `${id}-dev`,
473
478
  apply() {
474
479
  return !isBuild;
475
480
  },
476
481
  configureServer: (server) => {
477
- server.watcher.add(files).on("change", (p) => files.includes(p) && _buildEntry().then(() => (0, import_vite_plugin_electron.startup)()));
482
+ server.watcher.add(files).on(
483
+ "change",
484
+ (p) => files.includes(p) && _buildEntry().then(async () => {
485
+ await import_vite_plugin_electron.startup.exit();
486
+ await _postBuild();
487
+ await (0, import_vite_plugin_electron.startup)();
488
+ })
489
+ );
478
490
  }
479
491
  };
480
492
  }
@@ -483,5 +495,6 @@ function electronWithUpdater(options) {
483
495
  // Annotate the CommonJS export names for ESM import in node:
484
496
  0 && (module.exports = {
485
497
  debugStartup,
486
- electronWithUpdater
498
+ electronWithUpdater,
499
+ log
487
500
  });
package/dist/vite.mjs CHANGED
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-GB6VLKJZ.mjs";
9
9
 
10
10
  // src/vite.ts
11
- import { join as join2, resolve } from "node:path";
12
- import { rmSync } from "node:fs";
11
+ import { basename, join as join2, resolve } from "node:path";
12
+ import { cpSync, existsSync as existsSync3, rmSync } from "node:fs";
13
13
  import { createLogger, mergeConfig, normalizePath } from "vite";
14
14
  import ElectronSimple from "vite-plugin-electron/simple";
15
15
  import { startup } from "vite-plugin-electron";
@@ -17,8 +17,8 @@ import { notBundle } from "vite-plugin-electron/plugin";
17
17
 
18
18
  // src/build-plugins/build.ts
19
19
  import { readFile, rename, writeFile } from "node:fs/promises";
20
- import { cpSync, existsSync } from "node:fs";
21
- import { basename, join } from "node:path";
20
+ import { existsSync } from "node:fs";
21
+ import { join } from "node:path";
22
22
  import Asar from "@electron/asar";
23
23
  import { build } from "esbuild";
24
24
  async function buildAsar({
@@ -61,7 +61,7 @@ async function buildVersion({
61
61
  if (isUpdateJSON(oldVersionJson)) {
62
62
  _json = oldVersionJson;
63
63
  } else {
64
- console.warn("old version json is invalid, ignore it");
64
+ log.warn("old version json is invalid, ignore it");
65
65
  }
66
66
  } catch (error) {
67
67
  }
@@ -95,8 +95,7 @@ async function buildEntry({
95
95
  appEntryPath,
96
96
  entryOutputDirPath,
97
97
  nativeModuleEntryMap,
98
- overrideEsbuildOptions,
99
- postBuild
98
+ overrideEsbuildOptions
100
99
  }) {
101
100
  await build({
102
101
  entryPoints: {
@@ -116,19 +115,6 @@ async function buildEntry({
116
115
  },
117
116
  ...overrideEsbuildOptions
118
117
  });
119
- await postBuild?.({
120
- getPathFromEntryOutputDir(...paths) {
121
- return join(entryOutputDirPath, ...paths);
122
- },
123
- existsAndCopyToEntryOutputDir({ from, to, skipIfExist = true }) {
124
- if (existsSync(from)) {
125
- const target = join(entryOutputDirPath, to ?? basename(from));
126
- if (!skipIfExist || !existsSync(target)) {
127
- cpSync(from, target);
128
- }
129
- }
130
- }
131
- });
132
118
  }
133
119
 
134
120
  // src/build-plugins/key.ts
@@ -181,7 +167,7 @@ function parseKeys({
181
167
  const keysDir = dirname(privateKeyPath);
182
168
  !existsSync2(keysDir) && mkdirSync(keysDir);
183
169
  if (!existsSync2(privateKeyPath) || !existsSync2(certPath)) {
184
- console.warn("no key pair found, generate new key pair");
170
+ log.warn("no key pair found, generate new key pair");
185
171
  generateKeyPair(keyLength, parseSubjects(subject), days, privateKeyPath, certPath);
186
172
  }
187
173
  const privateKey = process.env.UPDATER_PK || readFileSync(privateKeyPath, "utf-8");
@@ -204,7 +190,7 @@ function parseOptions(isBuild, pkg, options = {}) {
204
190
  appEntryPath = "electron/entry.ts",
205
191
  nativeModuleEntryMap = {},
206
192
  postBuild,
207
- overrideEsbuildOptions
193
+ overrideEsbuildOptions = {}
208
194
  } = {},
209
195
  paths: {
210
196
  asarOutputPath = `release/${pkg.name}.asar`,
@@ -242,7 +228,6 @@ function parseOptions(isBuild, pkg, options = {}) {
242
228
  entryOutputDirPath,
243
229
  appEntryPath,
244
230
  nativeModuleEntryMap,
245
- postBuild,
246
231
  overrideEsbuildOptions
247
232
  };
248
233
  const { privateKey, cert } = parseKeys({
@@ -263,7 +248,7 @@ function parseOptions(isBuild, pkg, options = {}) {
263
248
  generateSignature,
264
249
  generateVersionJson
265
250
  };
266
- return { buildAsarOption, buildEntryOption, buildVersionOption };
251
+ return { buildAsarOption, buildEntryOption, buildVersionOption, postBuild };
267
252
  }
268
253
 
269
254
  // src/vite.ts
@@ -289,7 +274,7 @@ function electronWithUpdater(options) {
289
274
  } catch (ignore) {
290
275
  }
291
276
  log.info(`remove old files`, { timestamp: true });
292
- const { buildAsarOption, buildEntryOption, buildVersionOption } = _options;
277
+ const { buildAsarOption, buildEntryOption, buildVersionOption, postBuild } = _options;
293
278
  const { entryOutputDirPath, nativeModuleEntryMap, appEntryPath } = buildEntryOption;
294
279
  const sourcemap = isBuild || !!process.env.VSCODE_DEBUG;
295
280
  const _appPath = join2(entryOutputDirPath, "entry.js");
@@ -301,6 +286,24 @@ function electronWithUpdater(options) {
301
286
  await buildEntry(buildEntryOption);
302
287
  log.info(`build entry to '${entryOutputDirPath}'`, { timestamp: true });
303
288
  };
289
+ const _postBuild = postBuild ? async () => postBuild({
290
+ getPathFromEntryOutputDir(...paths) {
291
+ return join2(entryOutputDirPath, ...paths);
292
+ },
293
+ existsAndCopyToEntryOutputDir({ from, to, skipIfExist = true }) {
294
+ if (existsSync3(from)) {
295
+ const target = join2(entryOutputDirPath, to ?? basename(from));
296
+ if (!skipIfExist || !existsSync3(target)) {
297
+ try {
298
+ cpSync(from, target);
299
+ } catch (ignore) {
300
+ log.warn(`copy failed: ${ignore}`);
301
+ }
302
+ }
303
+ }
304
+ }
305
+ }) : async () => {
306
+ };
304
307
  const electronPluginOptions = {
305
308
  main: {
306
309
  entry: _main.files,
@@ -308,8 +311,9 @@ function electronWithUpdater(options) {
308
311
  if (!isInit) {
309
312
  isInit = true;
310
313
  await _buildEntry();
314
+ await _postBuild();
311
315
  }
312
- _main.onstart?.(args) ?? args.startup();
316
+ _main.onstart ? _main.onstart(args) : args.startup();
313
317
  },
314
318
  vite: mergeConfig(
315
319
  {
@@ -380,7 +384,14 @@ function electronWithUpdater(options) {
380
384
  return !isBuild;
381
385
  },
382
386
  configureServer: (server) => {
383
- server.watcher.add(files).on("change", (p) => files.includes(p) && _buildEntry().then(() => startup()));
387
+ server.watcher.add(files).on(
388
+ "change",
389
+ (p) => files.includes(p) && _buildEntry().then(async () => {
390
+ await startup.exit();
391
+ await _postBuild();
392
+ await startup();
393
+ })
394
+ );
384
395
  }
385
396
  };
386
397
  }
@@ -388,5 +399,6 @@ function electronWithUpdater(options) {
388
399
  }
389
400
  export {
390
401
  debugStartup,
391
- electronWithUpdater
402
+ electronWithUpdater,
403
+ log
392
404
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electron-incremental-update",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "electron incremental update tools, powered by vite",
5
5
  "author": "subframe7536",
6
6
  "license": "MIT",
@@ -49,21 +49,21 @@
49
49
  "vite-plugin-electron": "^0.15.6 || ^0.28"
50
50
  },
51
51
  "dependencies": {
52
- "@electron/asar": "^3.2.8",
53
- "@subframe7536/type-utils": "^0.1.4",
52
+ "@electron/asar": "^3.2.9",
53
+ "@subframe7536/type-utils": "^0.1.6",
54
54
  "selfsigned": "^2.4.1"
55
55
  },
56
56
  "devDependencies": {
57
- "@subframe7536/eslint-config": "^0.5.9",
58
- "@types/node": "^20.11.5",
59
- "bumpp": "^9.3.0",
57
+ "@subframe7536/eslint-config": "^0.6.0",
58
+ "@types/node": "^20.12.5",
59
+ "bumpp": "^9.4.0",
60
60
  "electron": "28.1.1",
61
- "eslint": "^8.56.0",
62
- "tsup": "^8.0.1",
63
- "typescript": "^5.3.3",
64
- "vite": "^5.0.12",
65
- "vite-plugin-electron": "^0.15.6",
66
- "vitest": "^1.2.1"
61
+ "eslint": "^8.57.0",
62
+ "tsup": "^8.0.2",
63
+ "typescript": "^5.4.4",
64
+ "vite": "^5.2.8",
65
+ "vite-plugin-electron": "^0.28.4",
66
+ "vitest": "^1.4.0"
67
67
  },
68
68
  "pnpm": {
69
69
  "overrides": {