electron-incremental-update 2.3.7 → 2.4.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 CHANGED
@@ -103,7 +103,6 @@ export default defineConfig(async ({ command }) => {
103
103
  plugins: [
104
104
  electronWithUpdater({
105
105
  isBuild,
106
- logParsedOptions: true,
107
106
  main: {
108
107
  files: ['./electron/main/index.ts', './electron/main/worker.ts'],
109
108
  // see https://github.com/electron-vite/electron-vite-vue/blob/85ed267c4851bf59f32888d766c0071661d4b94c/vite.config.ts#L22-L28
@@ -278,7 +277,7 @@ const plugin = electronWithUpdater({
278
277
  db: './electron/native/db.ts',
279
278
  img: './electron/native/img.ts',
280
279
  },
281
- postBuild: async ({ copyToEntryOutputDir, copyModules }) => {
280
+ postBuild: ({ copyToEntryOutputDir, copyModules }) => {
282
281
  // for better-sqlite3
283
282
  copyToEntryOutputDir({
284
283
  from: './node_modules/better-sqlite3/build/Release/better_sqlite3.node',
@@ -286,7 +285,7 @@ const plugin = electronWithUpdater({
286
285
  })
287
286
  // for @napi-rs/image
288
287
  const startStr = '@napi-rs+image-'
289
- const fileName = (await readdir('./node_modules/.pnpm')).filter(p => p.startsWith(startStr))[0]
288
+ const fileName = readdirSync('./node_modules/.pnpm').find(p => p.startsWith(startStr))!
290
289
  const archName = fileName.substring(startStr.length).split('@')[0]
291
290
  copyToEntryOutputDir({
292
291
  from: `./node_modules/.pnpm/${fileName}/node_modules/@napi-rs/image-${archName}/image.${archName}.node`,
@@ -350,6 +349,74 @@ module.exports = {
350
349
  }
351
350
  ```
352
351
 
352
+ #### Result in app.asar
353
+
354
+ Before: Redundant 🤮
355
+
356
+ ```
357
+ .
358
+ ├── dist-entry
359
+ │ ├── chunk-IVHNGRZY-BPUeB0jT.js
360
+ │ ├── db.js
361
+ │ ├── entry.js
362
+ │ └── image.js
363
+ ├── node_modules
364
+ │ ├── @napi-rs
365
+ │ ├── base64-js
366
+ │ ├── better-sqlite3
367
+ │ ├── bindings
368
+ │ ├── bl
369
+ │ ├── buffer
370
+ │ ├── chownr
371
+ │ ├── decompress-response
372
+ │ ├── deep-extend
373
+ │ ├── detect-libc
374
+ │ ├── end-of-stream
375
+ │ ├── expand-template
376
+ │ ├── file-uri-to-path
377
+ │ ├── fs-constants
378
+ │ ├── github-from-package
379
+ │ ├── ieee754
380
+ │ ├── inherits
381
+ │ ├── ini
382
+ │ ├── mimic-response
383
+ │ ├── minimist
384
+ │ ├── mkdirp-classic
385
+ │ ├── napi-build-utils
386
+ │ ├── node-abi
387
+ │ ├── once
388
+ │ ├── prebuild-install
389
+ │ ├── pump
390
+ │ ├── rc
391
+ │ ├── readable-stream
392
+ │ ├── safe-buffer
393
+ │ ├── semver
394
+ │ ├── simple-concat
395
+ │ ├── simple-get
396
+ │ ├── string_decoder
397
+ │ ├── strip-json-comments
398
+ │ ├── tar-fs
399
+ │ ├── tar-stream
400
+ │ ├── tunnel-agent
401
+ │ ├── util-deprecate
402
+ │ └── wrappy
403
+ └── package.json
404
+ ```
405
+
406
+ After: Clean 😍
407
+
408
+ ```
409
+ .
410
+ ├── dist-entry
411
+ │ ├── better_sqlite3.node
412
+ │ ├── chunk-IVHNGRZY-BPUeB0jT.js
413
+ │ ├── db.js
414
+ │ ├── entry.js
415
+ │ ├── image.js
416
+ │ └── image.win32-x64-msvc.node
417
+ └── package.json
418
+ ```
419
+
353
420
  ### Bytecode Protection
354
421
 
355
422
  Use V8 cache to protect the source code
@@ -756,12 +823,6 @@ export interface ElectronWithUpdaterOptions {
756
823
  * @default isCI
757
824
  */
758
825
  buildVersionJson?: boolean
759
- /**
760
- * Whether to log parsed options
761
- *
762
- * To show certificate and private keys, set `logParsedOptions: { showKeys: true }`
763
- */
764
- logParsedOptions?: boolean | { showKeys: boolean }
765
826
  /**
766
827
  * Main process options
767
828
  *
@@ -923,7 +984,9 @@ export interface BuildEntryOption {
923
984
  /**
924
985
  * `external` option in `build.rollupOptions`,
925
986
  * default is node built-in modules or native modules.
926
- * If is in dev, also external `dependencies` in package.json
987
+ *
988
+ * If is in dev and {@link postBuild} is not setup, will also
989
+ * external `dependencies` in `package.json`
927
990
  */
928
991
  external?: NonNullable<NonNullable<InlineConfig['build']>['rollupOptions']>['external']
929
992
  /**
@@ -944,8 +1007,9 @@ export interface BuildEntryOption {
944
1007
  */
945
1008
  overrideViteOptions?: InlineConfig
946
1009
  /**
947
- * Resolve extra files on startup, such as `.node`
948
- * @remark won't trigger will reload
1010
+ * By default, all the unbundled modules will be packaged by packager like `electron-builder`.
1011
+ * If setup, all the `dependencies` in `package.json` will be bundled by default, and you need
1012
+ * to manually handle the native module files.
949
1013
  */
950
1014
  postBuild?: (args: {
951
1015
  /**
package/dist/index.cjs CHANGED
@@ -56,6 +56,7 @@ var Updater = class extends events.EventEmitter {
56
56
  controller;
57
57
  info;
58
58
  tmpFilePath;
59
+ processing = false;
59
60
  provider;
60
61
  /**
61
62
  * Updater logger
@@ -142,9 +143,17 @@ var Updater = class extends events.EventEmitter {
142
143
  async checkForUpdates(data) {
143
144
  const emitUnavailable = (msg, code, info2) => {
144
145
  this.logger?.info(`[${code}] ${msg}`);
146
+ this.logger?.debug("Check update end");
147
+ this.processing = false;
145
148
  this.emit("update-not-available", code, msg, info2);
146
149
  return false;
147
150
  };
151
+ if (this.processing) {
152
+ this.logger?.info("Updater is already processing, skip check update");
153
+ return false;
154
+ }
155
+ this.processing = true;
156
+ this.logger?.debug("Check update start");
148
157
  if (!data && !this.provider) {
149
158
  const msg = "No update json or provider";
150
159
  this.err("Check update failed", "ERR_PARAM", msg);
@@ -195,8 +204,10 @@ var Updater = class extends events.EventEmitter {
195
204
  );
196
205
  }
197
206
  this.logger?.info(`Update available: ${version}`);
198
- this.emit("update-available", extraVersionInfo);
199
207
  this.info = info;
208
+ this.processing = false;
209
+ this.logger?.debug("Check update end");
210
+ this.emit("update-available", extraVersionInfo);
200
211
  return true;
201
212
  } catch {
202
213
  const msg = "Fail to parse version string";
@@ -209,41 +220,45 @@ var Updater = class extends events.EventEmitter {
209
220
  }
210
221
  }
211
222
  async downloadUpdate(data, info) {
223
+ const emitError = (code, errorInfo) => {
224
+ this.err(`Download update failed`, code, errorInfo);
225
+ this.logger?.debug("Download update end");
226
+ this.processing = false;
227
+ return false;
228
+ };
229
+ if (this.processing) {
230
+ this.logger?.info("Updater is already processing, skip download update");
231
+ return false;
232
+ }
233
+ this.processing = true;
234
+ this.logger?.debug("Download update start");
212
235
  const _sig = info?.signature ?? this.info?.signature;
213
236
  const _version = info?.version ?? this.info?.version;
214
237
  if (!_sig || !_version) {
215
- this.err(
216
- "Download failed",
238
+ return emitError(
217
239
  "ERR_PARAM",
218
240
  "No update signature, please call `checkUpdate` first or manually setup params"
219
241
  );
220
- return false;
221
242
  }
222
243
  if (!data && !this.provider) {
223
- this.err(
224
- "Download failed",
244
+ return emitError(
225
245
  "ERR_PARAM",
226
246
  "No update asar buffer and provider"
227
247
  );
228
- return false;
229
248
  }
230
249
  const buffer = await this.fetch("buffer", data ? Buffer.from(data) : void 0);
231
250
  if (!buffer) {
232
- this.err(
233
- "Download failed",
251
+ return emitError(
234
252
  "ERR_PARAM",
235
253
  "No update asar file buffer"
236
254
  );
237
- return false;
238
255
  }
239
256
  this.logger?.debug("Validation start");
240
257
  if (!await this.provider.verifySignaure(buffer, _version, _sig, this.CERT)) {
241
- this.err(
242
- "Download failed",
258
+ return emitError(
243
259
  "ERR_VALIDATE",
244
260
  "Invalid update asar file"
245
261
  );
246
- return false;
247
262
  }
248
263
  this.logger?.debug("Validation end");
249
264
  try {
@@ -253,15 +268,15 @@ var Updater = class extends events.EventEmitter {
253
268
  this.logger?.info(`Download success, version: ${_version}`);
254
269
  this.info = void 0;
255
270
  this.emit("update-downloaded");
271
+ this.processing = false;
272
+ this.logger?.debug("Download update end");
256
273
  return true;
257
274
  } catch (error) {
258
275
  this.cleanup();
259
- this.err(
260
- "Download failed",
276
+ return emitError(
261
277
  "ERR_DOWNLOAD",
262
- `Fail to unwrap asar file, ${error}`
278
+ `Failed to write update file: ${error instanceof Error ? error.message : error}`
263
279
  );
264
- return false;
265
280
  }
266
281
  }
267
282
  /**
package/dist/index.d.cts CHANGED
@@ -62,6 +62,7 @@ declare class Updater<T extends UpdateInfoWithExtraVersion = UpdateInfoWithExtra
62
62
  private controller;
63
63
  private info?;
64
64
  private tmpFilePath?;
65
+ private processing;
65
66
  provider?: IProvider;
66
67
  /**
67
68
  * Updater logger
package/dist/index.d.ts CHANGED
@@ -62,6 +62,7 @@ declare class Updater<T extends UpdateInfoWithExtraVersion = UpdateInfoWithExtra
62
62
  private controller;
63
63
  private info?;
64
64
  private tmpFilePath?;
65
+ private processing;
65
66
  provider?: IProvider;
66
67
  /**
67
68
  * Updater logger
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ var Updater = class extends EventEmitter {
20
20
  controller;
21
21
  info;
22
22
  tmpFilePath;
23
+ processing = false;
23
24
  provider;
24
25
  /**
25
26
  * Updater logger
@@ -106,9 +107,17 @@ var Updater = class extends EventEmitter {
106
107
  async checkForUpdates(data) {
107
108
  const emitUnavailable = (msg, code, info2) => {
108
109
  this.logger?.info(`[${code}] ${msg}`);
110
+ this.logger?.debug("Check update end");
111
+ this.processing = false;
109
112
  this.emit("update-not-available", code, msg, info2);
110
113
  return false;
111
114
  };
115
+ if (this.processing) {
116
+ this.logger?.info("Updater is already processing, skip check update");
117
+ return false;
118
+ }
119
+ this.processing = true;
120
+ this.logger?.debug("Check update start");
112
121
  if (!data && !this.provider) {
113
122
  const msg = "No update json or provider";
114
123
  this.err("Check update failed", "ERR_PARAM", msg);
@@ -159,8 +168,10 @@ var Updater = class extends EventEmitter {
159
168
  );
160
169
  }
161
170
  this.logger?.info(`Update available: ${version}`);
162
- this.emit("update-available", extraVersionInfo);
163
171
  this.info = info;
172
+ this.processing = false;
173
+ this.logger?.debug("Check update end");
174
+ this.emit("update-available", extraVersionInfo);
164
175
  return true;
165
176
  } catch {
166
177
  const msg = "Fail to parse version string";
@@ -173,41 +184,45 @@ var Updater = class extends EventEmitter {
173
184
  }
174
185
  }
175
186
  async downloadUpdate(data, info) {
187
+ const emitError = (code, errorInfo) => {
188
+ this.err(`Download update failed`, code, errorInfo);
189
+ this.logger?.debug("Download update end");
190
+ this.processing = false;
191
+ return false;
192
+ };
193
+ if (this.processing) {
194
+ this.logger?.info("Updater is already processing, skip download update");
195
+ return false;
196
+ }
197
+ this.processing = true;
198
+ this.logger?.debug("Download update start");
176
199
  const _sig = info?.signature ?? this.info?.signature;
177
200
  const _version = info?.version ?? this.info?.version;
178
201
  if (!_sig || !_version) {
179
- this.err(
180
- "Download failed",
202
+ return emitError(
181
203
  "ERR_PARAM",
182
204
  "No update signature, please call `checkUpdate` first or manually setup params"
183
205
  );
184
- return false;
185
206
  }
186
207
  if (!data && !this.provider) {
187
- this.err(
188
- "Download failed",
208
+ return emitError(
189
209
  "ERR_PARAM",
190
210
  "No update asar buffer and provider"
191
211
  );
192
- return false;
193
212
  }
194
213
  const buffer = await this.fetch("buffer", data ? Buffer.from(data) : void 0);
195
214
  if (!buffer) {
196
- this.err(
197
- "Download failed",
215
+ return emitError(
198
216
  "ERR_PARAM",
199
217
  "No update asar file buffer"
200
218
  );
201
- return false;
202
219
  }
203
220
  this.logger?.debug("Validation start");
204
221
  if (!await this.provider.verifySignaure(buffer, _version, _sig, this.CERT)) {
205
- this.err(
206
- "Download failed",
222
+ return emitError(
207
223
  "ERR_VALIDATE",
208
224
  "Invalid update asar file"
209
225
  );
210
- return false;
211
226
  }
212
227
  this.logger?.debug("Validation end");
213
228
  try {
@@ -217,15 +232,15 @@ var Updater = class extends EventEmitter {
217
232
  this.logger?.info(`Download success, version: ${_version}`);
218
233
  this.info = void 0;
219
234
  this.emit("update-downloaded");
235
+ this.processing = false;
236
+ this.logger?.debug("Download update end");
220
237
  return true;
221
238
  } catch (error) {
222
239
  this.cleanup();
223
- this.err(
224
- "Download failed",
240
+ return emitError(
225
241
  "ERR_DOWNLOAD",
226
- `Fail to unwrap asar file, ${error}`
242
+ `Failed to write update file: ${error instanceof Error ? error.message : error}`
227
243
  );
228
- return false;
229
244
  }
230
245
  }
231
246
  /**
package/dist/provider.cjs CHANGED
@@ -337,6 +337,8 @@ var GitHubAtomProvider = class extends BaseGitHubProvider {
337
337
  return `releases/download/v${tag}/${versionPath}`;
338
338
  }
339
339
  };
340
+
341
+ // src/provider/github/file.ts
340
342
  var GitHubProvider = class extends BaseGitHubProvider {
341
343
  name = "GithubProvider";
342
344
  /**
package/dist/provider.js CHANGED
@@ -149,6 +149,8 @@ var GitHubAtomProvider = class extends BaseGitHubProvider {
149
149
  return `releases/download/v${tag}/${versionPath}`;
150
150
  }
151
151
  };
152
+
153
+ // src/provider/github/file.ts
152
154
  var GitHubProvider = class extends BaseGitHubProvider {
153
155
  name = "GithubProvider";
154
156
  /**
package/dist/vite.d.ts CHANGED
@@ -106,7 +106,9 @@ interface BuildEntryOption {
106
106
  /**
107
107
  * `external` option in `build.rollupOptions`,
108
108
  * default is node built-in modules or native modules.
109
- * If is in dev, also external `dependencies` in package.json
109
+ *
110
+ * If is in dev and {@link postBuild} is not setup, will also
111
+ * external `dependencies` in `package.json`
110
112
  */
111
113
  external?: NonNullable<NonNullable<InlineConfig['build']>['rollupOptions']>['external'];
112
114
  /**
@@ -127,8 +129,12 @@ interface BuildEntryOption {
127
129
  */
128
130
  overrideViteOptions?: InlineConfig;
129
131
  /**
130
- * Resolve extra files on startup, such as `.node`
131
- * @remark won't trigger will reload
132
+ * By default, all the unbundled modules will be packaged by packager like `electron-builder`.
133
+ * If setup, all the `dependencies` in `package.json` will be bundled by default, and you need
134
+ * to manually handle the native module files.
135
+ *
136
+ * If you are using `electron-buidler`, don't forget to append `'!node_modules/**'` in
137
+ * electron-build config's `files` array
132
138
  */
133
139
  postBuild?: (args: {
134
140
  /**
@@ -401,14 +407,6 @@ interface ElectronWithUpdaterOptions {
401
407
  * @default isCI
402
408
  */
403
409
  buildVersionJson?: boolean;
404
- /**
405
- * Whether to log parsed options
406
- *
407
- * To show certificate and private keys, set `logParsedOptions: { showKeys: true }`
408
- */
409
- logParsedOptions?: boolean | {
410
- showKeys: boolean;
411
- };
412
410
  /**
413
411
  * Main process options
414
412
  *
@@ -448,7 +446,6 @@ interface ElectronWithUpdaterOptions {
448
446
  * plugins: [
449
447
  * electronWithUpdater({
450
448
  * isBuild,
451
- * logParsedOptions: true,
452
449
  * main: {
453
450
  * files: ['./electron/main/index.ts', './electron/main/worker.ts'],
454
451
  * // see https://github.com/electron-vite/electron-vite-vue/blob/85ed267c4851bf59f32888d766c0071661d4b94c/vite.config.ts#L22-L28
package/dist/vite.js CHANGED
@@ -607,7 +607,7 @@ function parseOptions(isBuild, pkg, sourcemap = false, minify = false, options =
607
607
  /.*\.(node|dll|dylib|so)$/,
608
608
  "original-fs",
609
609
  ...builtinModules,
610
- ...isBuild ? [] : Object.keys("dependencies" in pkg ? pkg.dependencies : {})
610
+ ...isBuild || postBuild ? [] : Object.keys("dependencies" in pkg ? pkg.dependencies : {})
611
611
  ],
612
612
  overrideViteOptions = {}
613
613
  } = {},
@@ -735,8 +735,7 @@ async function electronWithUpdater(options) {
735
735
  buildVersionJson,
736
736
  updater,
737
737
  bytecode,
738
- useNotBundle = true,
739
- logParsedOptions
738
+ useNotBundle = true
740
739
  } = options;
741
740
  if (!pkg || !pkg.version || !pkg.name || !pkg.main) {
742
741
  log.error("package.json not found or invalid", { timestamp: true });
@@ -792,12 +791,12 @@ async function electronWithUpdater(options) {
792
791
  getPathFromEntryOutputDir(...paths) {
793
792
  return path5.join(entryOutputDirPath, ...paths);
794
793
  },
795
- copyToEntryOutputDir({ from, to, skipIfExist = true }) {
794
+ copyToEntryOutputDir({ from, to = path5.basename(from), skipIfExist = true }) {
796
795
  if (!fs5.existsSync(from)) {
797
796
  log.warn(`${from} not found`, { timestamp: true });
798
797
  return;
799
798
  }
800
- const target = path5.join(entryOutputDirPath, to ?? path5.basename(from));
799
+ const target = path5.join(entryOutputDirPath, to);
801
800
  copyAndSkipIfExist(from, target, skipIfExist);
802
801
  },
803
802
  copyModules({ modules, skipIfExist = true }) {
@@ -887,20 +886,6 @@ async function electronWithUpdater(options) {
887
886
  )
888
887
  }
889
888
  };
890
- if (logParsedOptions) {
891
- const shouldShowKey = typeof logParsedOptions === "object" && logParsedOptions.showKeys === true;
892
- log.info(
893
- JSON.stringify(
894
- {
895
- ...electronPluginOptions,
896
- updater: { buildAsarOption, buildEntryOption, buildVersionOption }
897
- },
898
- (key, value) => key === "privateKey" || key === "cert" ? shouldShowKey ? value : `<${key.toUpperCase()}>` : value,
899
- 2
900
- ),
901
- { timestamp: true }
902
- );
903
- }
904
889
  const result = [ElectronSimple(electronPluginOptions)];
905
890
  if (nativeModuleEntryMap) {
906
891
  const files = [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "electron-incremental-update",
3
3
  "type": "module",
4
- "version": "2.3.7",
4
+ "version": "2.4.0",
5
5
  "description": "Electron incremental update tools with Vite plugin, support bytecode protection",
6
6
  "author": "subframe7536",
7
7
  "license": "MIT",