ic-mops 0.45.4-pre.0 → 1.0.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/README.md +1 -1
  3. package/api/actors.ts +1 -1
  4. package/bundle/cli.tgz +0 -0
  5. package/cache.ts +15 -10
  6. package/cli.ts +27 -27
  7. package/commands/add.ts +4 -0
  8. package/commands/bench/bench-canister.mo +34 -8
  9. package/commands/bench-replica.ts +11 -6
  10. package/commands/bench.ts +29 -3
  11. package/commands/publish.ts +1 -1
  12. package/commands/replica.ts +239 -0
  13. package/commands/sources.ts +2 -3
  14. package/commands/test/mmf1.ts +10 -6
  15. package/commands/test/reporters/compact-reporter.ts +2 -1
  16. package/commands/test/reporters/files-reporter.ts +3 -2
  17. package/commands/test/reporters/reporter.ts +2 -1
  18. package/commands/test/reporters/silent-reporter.ts +2 -1
  19. package/commands/test/reporters/verbose-reporter.ts +14 -4
  20. package/commands/test/test.ts +214 -81
  21. package/commands/user.ts +71 -1
  22. package/declarations/bench/bench.did +6 -2
  23. package/declarations/bench/bench.did.d.ts +6 -2
  24. package/declarations/bench/bench.did.js +6 -2
  25. package/dist/cache.js +14 -10
  26. package/dist/cli.d.ts +1 -0
  27. package/dist/cli.js +23 -27
  28. package/dist/commands/add.js +3 -0
  29. package/dist/commands/bench/bench-canister.mo +34 -8
  30. package/dist/commands/bench-replica.d.ts +2 -1
  31. package/dist/commands/bench-replica.js +10 -6
  32. package/dist/commands/bench.js +27 -3
  33. package/dist/commands/publish.js +1 -1
  34. package/dist/commands/replica.d.ts +59 -0
  35. package/dist/commands/replica.js +195 -0
  36. package/dist/commands/sources.d.ts +2 -2
  37. package/dist/commands/sources.js +2 -3
  38. package/dist/commands/test/mmf1.d.ts +2 -2
  39. package/dist/commands/test/mmf1.js +9 -5
  40. package/dist/commands/test/reporters/compact-reporter.d.ts +2 -1
  41. package/dist/commands/test/reporters/compact-reporter.js +1 -1
  42. package/dist/commands/test/reporters/files-reporter.d.ts +2 -1
  43. package/dist/commands/test/reporters/files-reporter.js +2 -2
  44. package/dist/commands/test/reporters/reporter.d.ts +2 -1
  45. package/dist/commands/test/reporters/silent-reporter.d.ts +2 -1
  46. package/dist/commands/test/reporters/silent-reporter.js +1 -1
  47. package/dist/commands/test/reporters/verbose-reporter.d.ts +3 -1
  48. package/dist/commands/test/reporters/verbose-reporter.js +12 -4
  49. package/dist/commands/test/test.d.ts +10 -8
  50. package/dist/commands/test/test.js +171 -78
  51. package/dist/commands/user.d.ts +6 -0
  52. package/dist/commands/user.js +59 -1
  53. package/dist/declarations/bench/bench.did +6 -2
  54. package/dist/declarations/bench/bench.did.d.ts +6 -2
  55. package/dist/declarations/bench/bench.did.js +6 -2
  56. package/dist/mops.d.ts +1 -1
  57. package/dist/mops.js +5 -29
  58. package/dist/package.json +20 -21
  59. package/dist/release-cli.js +5 -2
  60. package/dist/resolve-packages.d.ts +2 -2
  61. package/dist/resolve-packages.js +29 -7
  62. package/dist/types.d.ts +1 -0
  63. package/dist/vessel.js +1 -1
  64. package/mops.ts +5 -32
  65. package/package.json +24 -24
  66. package/release-cli.ts +7 -2
  67. package/resolve-packages.ts +39 -8
  68. package/types.ts +3 -1
  69. package/vessel.ts +1 -1
  70. package/DEVELOPMENT.md +0 -25
  71. package/commands/import-identity.ts +0 -62
  72. package/commands/whoami.ts +0 -12
  73. package/dist/commands/import-identity.d.ts +0 -5
  74. package/dist/commands/import-identity.js +0 -51
  75. package/dist/commands/whoami.d.ts +0 -1
  76. package/dist/commands/whoami.js +0 -11
package/CHANGELOG.md CHANGED
@@ -1,7 +1,25 @@
1
1
  # Mops CLI Changelog
2
2
 
3
- ## unreleased
3
+ ## 1.0.0
4
4
  - `mops cache clean` now cleans local cache too (`.mops` folder)
5
+ - Conflicting dependencies are now reported on `mops add/install/sources`
6
+ - New `--conflicts <action>` option in `mops sources` command ([docs](https://docs.mops.one/cli/mops-sources#--conflicts))
7
+ - New "Stable Memory" and "Garbage Collection" metrics are now reported in the `mops bench` command
8
+ - `mops test` command now supports `replica` mode for running actor tests ([docs](https://docs.mops.one/cli/mops-test#--mode))
9
+ - New `--replica` option in `mops test` command
10
+ - Updated npm dependencies
11
+ - Fixed bug with GitHub dependency with branch name containing `/`
12
+
13
+ **Breaking changes**:
14
+ - Default replica in `mops bench` and `mops test` commands now is `pocket-ic` if `pocket-ic` is specified in `mops.toml` in `[toolchain]` section and `dfx` otherwise
15
+ - The only supported version of `pocket-ic` is `4.0.0`
16
+ - Dropped support for `wasmtime` version `< 14.0.0`
17
+ - Default reporter in `mops test` command is now `files` if test file count is > 1 and `verbose` otherwise.
18
+ - Renamed `mops import-identity` command to `mops user import`
19
+ - Renamed `mops whoami` command to `mops user get-principal`
20
+ - Removed the ability to install a specific package with `mops install <pkg>` command. Use `mops add <pkg>` instead.
21
+ - Removed legacy folders migration code. If you are using Mops CLI `<= 0.21.0`, you need first to run `npm i -g ic-mops@0.45.3` to migrate your legacy folders. After that, you can run `mops self update` to update your Mops CLI to the latest version.
22
+ - Removed `--verbose` flag from `mops sources` command
5
23
 
6
24
  ## 0.45.3
7
25
  - Fixed bug with missing `tar` package
package/README.md CHANGED
@@ -89,7 +89,7 @@ dfx identity new mops
89
89
  Import identity into `mops`
90
90
 
91
91
  ```
92
- mops import-identity -- "$(dfx identity export mops)"
92
+ mops user import -- "$(dfx identity export mops)"
93
93
  ```
94
94
 
95
95
  ### 2. Initialize
package/api/actors.ts CHANGED
@@ -8,7 +8,7 @@ import {_SERVICE as _STORAGE_SERVICE} from '../declarations/storage/storage.did.
8
8
  import {getEndpoint} from './network.js';
9
9
  import {getNetwork} from './network.js';
10
10
 
11
- let agentPromiseByPrincipal = new Map <string, Promise<HttpAgent>>();
11
+ let agentPromiseByPrincipal = new Map<string, Promise<HttpAgent>>();
12
12
 
13
13
  let getAgent = async (identity ?: Identity) : Promise<HttpAgent> => {
14
14
  let principal = identity ? identity?.getPrincipal().toText() : '';
package/bundle/cli.tgz ADDED
Binary file
package/cache.ts CHANGED
@@ -3,15 +3,20 @@ import path from 'node:path';
3
3
  import ncp from 'ncp';
4
4
  import getFolderSize from 'get-folder-size';
5
5
 
6
- import {getDependencyType, getRootDir, globalCacheDir, parseGithubURL} from './mops.js';
6
+ import {getDependencyType, getNetwork, getRootDir, globalCacheDir, parseGithubURL} from './mops.js';
7
7
  import {getPackageId} from './helpers/get-package-id.js';
8
8
 
9
+ let getGlobalCacheDir = () => {
10
+ let network = getNetwork();
11
+ return path.join(globalCacheDir, network === 'ic' ? '' : network);
12
+ };
13
+
9
14
  export let show = () => {
10
- return globalCacheDir;
15
+ return getGlobalCacheDir();
11
16
  };
12
17
 
13
18
  export let getDepCacheDir = (cacheName : string) => {
14
- return path.join(globalCacheDir, 'packages', cacheName);
19
+ return path.join(getGlobalCacheDir(), 'packages', cacheName);
15
20
  };
16
21
 
17
22
  export let isDepCached = (cacheName : string) => {
@@ -30,11 +35,11 @@ export function getMopsDepCacheName(name : string, version : string) {
30
35
 
31
36
  export function getGithubDepCacheName(name : string, repo : string) {
32
37
  const {branch, commitHash} = parseGithubURL(repo);
33
- return `_github/${name}#${branch}` + (commitHash ? `@${commitHash}` : '');
38
+ return `_github/${name}#${branch.replaceAll('/', '___')}` + (commitHash ? `@${commitHash}` : '');
34
39
  }
35
40
 
36
41
  export let addCache = (cacheName : string, source : string) => {
37
- let dest = path.join(globalCacheDir, 'packages', cacheName);
42
+ let dest = path.join(getGlobalCacheDir(), 'packages', cacheName);
38
43
  fs.mkdirSync(dest, {recursive: true});
39
44
 
40
45
  return new Promise<void>((resolve, reject) => {
@@ -48,7 +53,7 @@ export let addCache = (cacheName : string, source : string) => {
48
53
  };
49
54
 
50
55
  export let copyCache = (cacheName : string, dest : string) => {
51
- let source = path.join(globalCacheDir, 'packages', cacheName);
56
+ let source = path.join(getGlobalCacheDir(), 'packages', cacheName);
52
57
  fs.mkdirSync(dest, {recursive: true});
53
58
 
54
59
  return new Promise<void>((resolve, reject) => {
@@ -62,7 +67,7 @@ export let copyCache = (cacheName : string, dest : string) => {
62
67
  };
63
68
 
64
69
  export let cacheSize = async () => {
65
- let dir = path.join(globalCacheDir);
70
+ let dir = path.join(getGlobalCacheDir());
66
71
  fs.mkdirSync(dir, {recursive: true});
67
72
 
68
73
  let size = await getFolderSize.strict(dir);
@@ -73,13 +78,13 @@ export let cacheSize = async () => {
73
78
  };
74
79
 
75
80
  export let cleanCache = async () => {
76
- if (!globalCacheDir.endsWith('mops/cache') && !globalCacheDir.endsWith('/mops')) {
77
- throw new Error('Invalid cache directory: ' + globalCacheDir);
81
+ if (!getGlobalCacheDir().endsWith('mops/cache') && !getGlobalCacheDir().endsWith('/mops') && !getGlobalCacheDir().endsWith('/mops/' + getNetwork())) {
82
+ throw new Error('Invalid cache directory: ' + getGlobalCacheDir());
78
83
  }
79
84
 
80
85
  // local cache
81
86
  fs.rmSync(path.join(getRootDir(), '.mops'), {recursive: true, force: true});
82
87
 
83
88
  // global cache
84
- fs.rmSync(globalCacheDir, {recursive: true, force: true});
89
+ fs.rmSync(getGlobalCacheDir(), {recursive: true, force: true});
85
90
  };
package/cli.ts CHANGED
@@ -1,15 +1,12 @@
1
1
  import process from 'node:process';
2
2
  import fs from 'node:fs';
3
3
  import {Command, Argument, Option} from 'commander';
4
- import chalk from 'chalk';
5
4
 
6
5
  import {init} from './commands/init.js';
7
6
  import {publish} from './commands/publish.js';
8
- import {importPem} from './commands/import-identity.js';
9
7
  import {sources} from './commands/sources.js';
10
8
  import {checkApiCompatibility, setNetwork, apiVersion, checkConfigFile, getNetworkFile, version} from './mops.js';
11
9
  import {getNetwork} from './api/network.js';
12
- import {whoami} from './commands/whoami.js';
13
10
  import {installAll} from './commands/install/install-all.js';
14
11
  import {search} from './commands/search.js';
15
12
  import {add} from './commands/add.js';
@@ -17,7 +14,7 @@ import {cacheSize, cleanCache, show} from './cache.js';
17
14
  import {test} from './commands/test/test.js';
18
15
  import {template} from './commands/template.js';
19
16
  import {remove} from './commands/remove.js';
20
- import {getUserProp, setUserProp} from './commands/user.js';
17
+ import {importPem, getPrincipal, getUserProp, setUserProp} from './commands/user.js';
21
18
  import {bump} from './commands/bump.js';
22
19
  import {sync} from './commands/sync.js';
23
20
  import {outdated} from './commands/outdated.js';
@@ -27,11 +24,14 @@ import {transferOwnership} from './commands/transfer-ownership.js';
27
24
  import {toolchain} from './commands/toolchain/index.js';
28
25
  import {Tool} from './types.js';
29
26
  import * as self from './commands/self.js';
27
+ import {resolvePackages} from './resolve-packages.js';
30
28
  // import {docs} from './commands/docs.js';
31
29
 
32
30
  declare global {
33
31
  // eslint-disable-next-line no-var
34
32
  var MOPS_NETWORK : string;
33
+ // eslint-disable-next-line no-var
34
+ var mopsReplicaTestRunning : boolean;
35
35
  }
36
36
 
37
37
  let networkFile = getNetworkFile();
@@ -87,12 +87,12 @@ program
87
87
 
88
88
  // install
89
89
  program
90
- .command('install [pkg]')
90
+ .command('install')
91
91
  .alias('i')
92
92
  .description('Install all dependencies specified in mops.toml')
93
93
  .option('--verbose')
94
94
  .addOption(new Option('--lock <action>', 'Lockfile action').choices(['check', 'update', 'ignore']))
95
- .action(async (pkg, options) => {
95
+ .action(async (options) => {
96
96
  if (!checkConfigFile()) {
97
97
  process.exit(1);
98
98
  }
@@ -104,17 +104,14 @@ program
104
104
 
105
105
  await toolchain.ensureToolchainInited({strict: false});
106
106
 
107
- if (pkg) {
108
- // @deprecated
109
- console.log(chalk.yellow('Consider using the \'mops add\' command to install a specific package.'));
110
- await add(pkg, options);
111
- }
112
- else {
113
- let ok = await installAll(options);
114
- await toolchain.installAll(options);
115
- if (!ok) {
116
- process.exit(1);
117
- }
107
+ let ok = await installAll(options);
108
+ await toolchain.installAll(options);
109
+
110
+ // check conflicts
111
+ await resolvePackages({conflicts: 'warning'});
112
+
113
+ if (!ok) {
114
+ process.exit(1);
118
115
  }
119
116
  });
120
117
 
@@ -155,14 +152,14 @@ program
155
152
  console.log(getNetwork());
156
153
  });
157
154
 
158
- // import-identity
155
+ // user import
159
156
  program
160
- .command('import-identity <data>')
157
+ .command('mops user import <data>')
161
158
  .description('Import .pem file data to use as identity')
162
159
  .addOption(new Option('--no-encrypt', 'Do not ask for a password to encrypt identity'))
163
160
  .action(async (data, options) => {
164
161
  await importPem(data, options);
165
- await whoami();
162
+ await getPrincipal();
166
163
  });
167
164
 
168
165
  // sources
@@ -170,7 +167,7 @@ program
170
167
  .command('sources')
171
168
  .description('for dfx packtool')
172
169
  .option('--no-install', 'Do not install dependencies before running sources')
173
- .option('--verbose')
170
+ .addOption(new Option('--conflicts <action>', 'What to do with dependency version conflicts').choices(['ignore', 'warning', 'error']).default('warning'))
174
171
  .action(async (options) => {
175
172
  if (!checkConfigFile()) {
176
173
  process.exit(1);
@@ -183,12 +180,12 @@ program
183
180
  console.log(sourcesArr.join('\n'));
184
181
  });
185
182
 
186
- // whoami
183
+ // get-principal
187
184
  program
188
- .command('whoami')
185
+ .command('get-principal')
189
186
  .description('Print your principal')
190
187
  .action(async () => {
191
- await whoami();
188
+ await getPrincipal();
192
189
  });
193
190
 
194
191
  // search
@@ -222,10 +219,12 @@ program
222
219
  program
223
220
  .command('test [filter]')
224
221
  .description('Run tests')
225
- .addOption(new Option('-r, --reporter <reporter>', 'Test reporter').choices(['verbose', 'compact', 'files', 'silent']).default('verbose'))
226
- .addOption(new Option('--mode <mode>', 'Test mode').choices(['interpreter', 'wasi']).default('interpreter'))
222
+ .addOption(new Option('-r, --reporter <reporter>', 'Test reporter').choices(['verbose', 'compact', 'files', 'silent']))
223
+ .addOption(new Option('--mode <mode>', 'Test mode').choices(['interpreter', 'wasi', 'replica']).default('interpreter'))
224
+ .addOption(new Option('--replica <replica>', 'Which replica to use to run tests in replica mode').choices(['dfx', 'pocket-ic']))
227
225
  .option('-w, --watch', 'Enable watch mode')
228
226
  .action(async (filter, options) => {
227
+ checkConfigFile(true);
229
228
  await installAll({silent: true, lock: 'ignore'});
230
229
  await test(filter, options);
231
230
  });
@@ -234,13 +233,14 @@ program
234
233
  program
235
234
  .command('bench [filter]')
236
235
  .description('Run benchmarks')
237
- .addOption(new Option('--replica <replica>', 'Which replica to use to run benchmarks').choices(['dfx', 'pocket-ic']).default('dfx'))
236
+ .addOption(new Option('--replica <replica>', 'Which replica to use to run benchmarks').choices(['dfx', 'pocket-ic']))
238
237
  .addOption(new Option('--gc <gc>', 'Garbage collector').choices(['copying', 'compacting', 'generational', 'incremental']).default('copying'))
239
238
  .addOption(new Option('--save', 'Save benchmark results to .bench/<filename>.json'))
240
239
  .addOption(new Option('--compare', 'Run benchmark and compare results with .bench/<filename>.json'))
241
240
  // .addOption(new Option('--force-gc', 'Force GC'))
242
241
  .addOption(new Option('--verbose', 'Show more information'))
243
242
  .action(async (filter, options) => {
243
+ checkConfigFile(true);
244
244
  await installAll({silent: true, lock: 'ignore'});
245
245
  await bench(filter, options);
246
246
  });
package/commands/add.ts CHANGED
@@ -10,6 +10,7 @@ import {checkIntegrity} from '../integrity.js';
10
10
  import {checkRequirements} from '../check-requirements.js';
11
11
  import {syncLocalCache} from './install/sync-local-cache.js';
12
12
  import {notifyInstalls} from '../notify-installs.js';
13
+ import {resolvePackages} from '../resolve-packages.js';
13
14
 
14
15
  type AddOptions = {
15
16
  verbose ?: boolean;
@@ -127,4 +128,7 @@ export async function add(name : string, {verbose = false, dev = false, lock} :
127
128
  await checkRequirements({verbose});
128
129
 
129
130
  console.log(chalk.green('Package installed ') + `${pkgDetails.name} = "${pkgDetails.repo || pkgDetails.path || pkgDetails.version}"`);
131
+
132
+ // check conflicts
133
+ await resolvePackages({conflicts: 'warning'});
130
134
  }
@@ -2,17 +2,35 @@ import Nat64 "mo:base/Nat64";
2
2
  import Nat "mo:base/Nat";
3
3
  import Debug "mo:base/Debug";
4
4
  import ExperimentalInternetComputer "mo:base/ExperimentalInternetComputer";
5
+ import ExperimentalStableMemory "mo:base/ExperimentalStableMemory";
6
+ import Int64 "mo:base/Int64";
7
+ import Region "mo:base/Region";
5
8
  import Prim "mo:prim";
6
9
  import Bench "mo:bench";
7
10
 
8
11
  import UserBench "./user-bench"; // file path will be replaced with the *.bench.mo file path
9
12
 
10
13
  actor class() {
14
+ type BenchResult = {
15
+ instructions : Int;
16
+ rts_mutator_instructions : Int;
17
+ stable_memory_size : Int;
18
+ rts_stable_memory_size : Int;
19
+ rts_logical_stable_memory_size : Int;
20
+ rts_collector_instructions : Int;
21
+ rts_heap_size : Int;
22
+ rts_memory_size : Int;
23
+ rts_total_allocation : Int;
24
+ rts_reclaimed : Int;
25
+ };
26
+
11
27
  var benchOpt : ?Bench.Bench = null;
12
28
 
13
29
  public func init() : async Bench.BenchSchema {
14
30
  let bench = UserBench.init();
15
31
  benchOpt := ?bench;
32
+ // ignore ExperimentalStableMemory.grow(1);
33
+ ignore Region.grow(Region.new(), 1);
16
34
  bench.getSchema();
17
35
  };
18
36
 
@@ -21,29 +39,37 @@ actor class() {
21
39
  bench.getSchema();
22
40
  };
23
41
 
24
- func _getStats() : Bench.BenchResult {
42
+ func _getStats() : BenchResult {
25
43
  {
26
44
  instructions = 0;
27
45
  rts_heap_size = Prim.rts_heap_size();
46
+ stable_memory_size = Int64.toInt(Int64.fromNat64(ExperimentalStableMemory.size())) * 65536;
47
+ rts_stable_memory_size = Prim.rts_stable_memory_size();
48
+ rts_logical_stable_memory_size = Prim.rts_logical_stable_memory_size();
28
49
  rts_memory_size = Prim.rts_memory_size();
29
50
  rts_total_allocation = Prim.rts_total_allocation();
51
+ rts_reclaimed = Prim.rts_reclaimed();
30
52
  rts_mutator_instructions = Prim.rts_mutator_instructions();
31
53
  rts_collector_instructions = Prim.rts_collector_instructions();
32
54
  }
33
55
  };
34
56
 
35
- func _diffStats(before : Bench.BenchResult, after : Bench.BenchResult) : Bench.BenchResult {
57
+ func _diffStats(before : BenchResult, after : BenchResult) : BenchResult {
36
58
  {
37
59
  instructions = after.instructions - before.instructions;
38
60
  rts_heap_size = after.rts_heap_size - before.rts_heap_size;
61
+ stable_memory_size = after.stable_memory_size - before.stable_memory_size;
62
+ rts_stable_memory_size = after.rts_stable_memory_size - before.rts_stable_memory_size;
63
+ rts_logical_stable_memory_size = after.rts_logical_stable_memory_size - before.rts_logical_stable_memory_size;
39
64
  rts_memory_size = after.rts_memory_size - before.rts_memory_size;
40
65
  rts_total_allocation = after.rts_total_allocation - before.rts_total_allocation;
66
+ rts_reclaimed = after.rts_reclaimed - before.rts_reclaimed;
41
67
  rts_mutator_instructions = after.rts_mutator_instructions - before.rts_mutator_instructions;
42
68
  rts_collector_instructions = after.rts_collector_instructions - before.rts_collector_instructions;
43
69
  }
44
70
  };
45
71
 
46
- func _runCell(rowIndex : Nat, colIndex : Nat) : Bench.BenchResult {
72
+ func _runCell(rowIndex : Nat, colIndex : Nat) : BenchResult {
47
73
  let ?bench = benchOpt else Debug.trap("bench not initialized");
48
74
  let statsBefore = _getStats();
49
75
 
@@ -55,7 +81,7 @@ actor class() {
55
81
  _diffStats(statsBefore, { statsAfter with instructions });
56
82
  };
57
83
 
58
- func _runCellAwait(rowIndex : Nat, colIndex : Nat) : async Bench.BenchResult {
84
+ func _runCellAwait(rowIndex : Nat, colIndex : Nat) : async BenchResult {
59
85
  let ?bench = benchOpt else Debug.trap("bench not initialized");
60
86
  let statsBefore = _getStats();
61
87
 
@@ -69,19 +95,19 @@ actor class() {
69
95
  _diffStats(statsBefore, { statsAfter with instructions });
70
96
  };
71
97
 
72
- public query func getStats() : async Bench.BenchResult {
98
+ public query func getStats() : async BenchResult {
73
99
  _getStats();
74
100
  };
75
101
 
76
- public query func runCellQuery(rowIndex : Nat, colIndex : Nat) : async Bench.BenchResult {
102
+ public query func runCellQuery(rowIndex : Nat, colIndex : Nat) : async BenchResult {
77
103
  _runCell(rowIndex, colIndex);
78
104
  };
79
105
 
80
- public func runCellUpdate(rowIndex : Nat, colIndex : Nat) : async Bench.BenchResult {
106
+ public func runCellUpdate(rowIndex : Nat, colIndex : Nat) : async BenchResult {
81
107
  _runCell(rowIndex, colIndex);
82
108
  };
83
109
 
84
- public func runCellUpdateAwait(rowIndex : Nat, colIndex : Nat) : async Bench.BenchResult {
110
+ public func runCellUpdateAwait(rowIndex : Nat, colIndex : Nat) : async BenchResult {
85
111
  await _runCellAwait(rowIndex, colIndex);
86
112
  };
87
113
  };
@@ -3,7 +3,7 @@ import {execSync} from 'node:child_process';
3
3
  import path from 'node:path';
4
4
  import fs from 'node:fs';
5
5
  import {execaCommand} from 'execa';
6
- import {PocketIc} from 'pic-ic';
6
+ import {PocketIc, PocketIcServer} from 'pic-ic';
7
7
  import {getRootDir, readConfig} from '../mops.js';
8
8
  import {createActor, idlFactory} from '../declarations/bench/index.js';
9
9
  import {toolchain} from './toolchain/index.js';
@@ -12,6 +12,7 @@ export class BenchReplica {
12
12
  type : 'dfx' | 'pocket-ic';
13
13
  verbose = false;
14
14
  canisters : Record<string, {cwd : string; canisterId : string; actor : any;}> = {};
15
+ pocketIcServer ?: PocketIcServer;
15
16
  pocketIc ?: PocketIc;
16
17
 
17
18
  constructor(type : 'dfx' | 'pocket-ic', verbose = false) {
@@ -31,11 +32,14 @@ export class BenchReplica {
31
32
  else {
32
33
  let pocketIcBin = await toolchain.bin('pocket-ic');
33
34
  let config = readConfig();
34
- if (config.toolchain?.['pocket-ic'] !== '1.0.0') {
35
- console.error('Currently only pocket-ic 1.0.0 is supported');
35
+ if (config.toolchain?.['pocket-ic'] !== '4.0.0') {
36
+ console.error('Current Mops CLI only supports pocket-ic 4.0.0');
36
37
  process.exit(1);
37
38
  }
38
- this.pocketIc = await PocketIc.create(pocketIcBin);
39
+ this.pocketIcServer = await PocketIcServer.start({
40
+ binPath: pocketIcBin,
41
+ });
42
+ this.pocketIc = await PocketIc.create(this.pocketIcServer.getUrl());
39
43
  }
40
44
  }
41
45
 
@@ -44,8 +48,9 @@ export class BenchReplica {
44
48
  let dir = path.join(getRootDir(), '.mops/.bench');
45
49
  execSync('dfx stop' + (this.verbose ? '' : ' -qqqq'), {cwd: dir, stdio: ['pipe', this.verbose ? 'inherit' : 'ignore', 'pipe']});
46
50
  }
47
- else if (this.pocketIc) {
51
+ else if (this.pocketIc && this.pocketIcServer) {
48
52
  await this.pocketIc.tearDown();
53
+ await this.pocketIcServer.stop();
49
54
  }
50
55
  }
51
56
 
@@ -61,7 +66,7 @@ export class BenchReplica {
61
66
  this.canisters[name] = {cwd, canisterId, actor};
62
67
  }
63
68
  else if (this.pocketIc) {
64
- let {canisterId, actor} = await this.pocketIc.setupCanister(idlFactory, wasm);
69
+ let {canisterId, actor} = await this.pocketIc.setupCanister({idlFactory, wasm});
65
70
  this.canisters[name] = {
66
71
  cwd,
67
72
  canisterId: canisterId.toText(),
package/commands/bench.ts CHANGED
@@ -20,6 +20,7 @@ import {sources} from './sources.js';
20
20
  import {Benchmark, Benchmarks} from '../declarations/main/main.did.js';
21
21
  import {BenchResult, _SERVICE} from '../declarations/bench/bench.did.js';
22
22
  import {BenchReplica} from './bench-replica.js';
23
+ import {filesize} from 'filesize';
23
24
 
24
25
  let ignore = [
25
26
  '**/node_modules/**',
@@ -48,8 +49,10 @@ type BenchOptions = {
48
49
  };
49
50
 
50
51
  export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}) : Promise<Benchmarks> {
52
+ let config = readConfig();
53
+
51
54
  let defaultOptions : BenchOptions = {
52
- replica: 'dfx',
55
+ replica: config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx',
53
56
  replicaVersion: '',
54
57
  compiler: 'moc',
55
58
  compilerVersion: getMocVersion(),
@@ -67,7 +70,6 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
67
70
  options.replicaVersion = getDfxVersion();
68
71
  }
69
72
  else if (options.replica == 'pocket-ic') {
70
- let config = readConfig();
71
73
  options.replicaVersion = config.toolchain?.['pocket-ic'] || '';
72
74
  }
73
75
 
@@ -219,11 +221,17 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
219
221
 
220
222
  let instructionsCells : bigint[][] = Array.from({length: schema.rows.length}, () => []);
221
223
  let heapCells : bigint[][] = Array.from({length: schema.rows.length}, () => []);
224
+ let logicalStableMemoryCells : bigint[][] = Array.from({length: schema.rows.length}, () => []);
225
+ let reclaimedCells : bigint[][] = Array.from({length: schema.rows.length}, () => []);
222
226
 
223
227
  let formatNumber = (n : bigint | number) : string => {
224
228
  return n.toLocaleString('en-US').replaceAll(',', '_');
225
229
  };
226
230
 
231
+ let formatSize = (n : bigint | number) : string => {
232
+ return filesize(n, {standard: 'iec', round: 2});
233
+ };
234
+
227
235
  let getTable = (prop : keyof BenchResult) : string => {
228
236
  let resArr = [['', ...schema.cols]];
229
237
 
@@ -251,7 +259,17 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
251
259
  }
252
260
 
253
261
  // add to table
254
- curRow.push(formatNumber(res[prop]) + diff);
262
+ let value = '';
263
+ if (prop == 'rts_logical_stable_memory_size') {
264
+ value = formatSize(res[prop] * 65536n);
265
+ }
266
+ else if (prop === 'rts_heap_size' || prop == 'rts_reclaimed') {
267
+ value = formatSize(res[prop]);
268
+ }
269
+ else {
270
+ value = formatNumber(res[prop]);
271
+ }
272
+ curRow.push(value + diff);
255
273
  }
256
274
  else {
257
275
  curRow.push('');
@@ -272,6 +290,8 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
272
290
  ${schema.description ? '\n' + chalk.gray(schema.description) : ''}
273
291
  \n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
274
292
  \n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
293
+ \n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}
294
+ \n\n${chalk.blue('Garbage Collection')}\n\n${getTable('rts_reclaimed')}
275
295
  `);
276
296
  };
277
297
 
@@ -289,6 +309,10 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
289
309
  instructionsCells[rowIndex][colIndex] = res.instructions;
290
310
  // @ts-ignore
291
311
  heapCells[rowIndex][colIndex] = res.rts_heap_size;
312
+ // @ts-ignore
313
+ logicalStableMemoryCells[rowIndex][colIndex] = res.rts_logical_stable_memory_size;
314
+ // @ts-ignore
315
+ reclaimedCells[rowIndex][colIndex] = res.rts_reclaimed;
292
316
 
293
317
  if (!process.env.CI && !options.silent) {
294
318
  printResults();
@@ -340,6 +364,8 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
340
364
  metrics: [
341
365
  ['instructions', instructionsCells],
342
366
  ['rts_heap_size', heapCells],
367
+ ['rts_logical_stable_memory_size', logicalStableMemoryCells],
368
+ ['rts_reclaimed', reclaimedCells],
343
369
  ],
344
370
  };
345
371
  }
@@ -271,7 +271,7 @@ export async function publish(options : {docs ?: boolean, test ?: boolean, bench
271
271
  let reporter = new SilentReporter;
272
272
  if (options.test) {
273
273
  console.log('Running tests...');
274
- await testWithReporter(reporter);
274
+ await testWithReporter(reporter, '', 'interpreter', config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx');
275
275
  if (reporter.failed > 0) {
276
276
  console.log(chalk.red('Error: ') + 'tests failed');
277
277
  process.exit(1);