@jskit-ai/kernel 0.1.147 → 0.1.149

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.
@@ -1,5 +1,5 @@
1
1
  import assert from "node:assert/strict";
2
- import { mkdtemp, mkdir, writeFile } from "node:fs/promises";
2
+ import { access, mkdtemp, mkdir, readFile, writeFile } from "node:fs/promises";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
5
  import test from "node:test";
@@ -23,47 +23,71 @@ async function writeJson(filePath, value) {
23
23
  await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
24
24
  }
25
25
 
26
- async function writeDescriptor(filePath, descriptor) {
27
- await writeFile(filePath, `export default ${JSON.stringify(descriptor, null, 2)};\n`, "utf8");
26
+ async function writePackageMetadata(packageRoot, packageMetadata) {
27
+ const packageJsonPath = path.join(packageRoot, "package.json");
28
+ const packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
29
+ const { packageId, version, description, ...jskit } = packageMetadata;
30
+ packageJson.name = packageId || packageJson.name;
31
+ packageJson.version = version || packageJson.version;
32
+ if (description) {
33
+ packageJson.description = description;
34
+ }
35
+ packageJson.jskit = Object.keys(jskit).length > 0 ? jskit : { kind: "runtime" };
36
+ await writeJson(packageJsonPath, packageJson);
28
37
  }
29
38
 
30
- test("resolveLocalPackageSources includes every lock-classified local package regardless of scope or exports", async () => {
31
- const tempRoot = await mkdtemp(path.join(os.tmpdir(), "jskit-client-bootstrap-local-resolution-"));
32
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
33
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
34
- lockVersion: 1,
35
- installedPackages: {
36
- "@local/main": {
37
- source: {
38
- type: "local-package",
39
- packagePath: "packages/main"
40
- }
41
- },
42
- "@local/feature": {
43
- source: {
44
- type: "app-local-package",
45
- packagePath: "packages/feature"
46
- }
47
- },
48
- "@example/local-utility": {
49
- source: {
50
- type: "local-package",
51
- packagePath: "packages/utility"
52
- }
53
- },
54
- "@example/published": {
55
- source: {
56
- type: "npm",
57
- packagePath: "packages/published"
58
- }
59
- }
39
+ async function pathExists(filePath) {
40
+ try {
41
+ await access(filePath);
42
+ return true;
43
+ } catch {
44
+ return false;
45
+ }
46
+ }
47
+
48
+ async function declareInstalledPackages(appRoot, packages = {}) {
49
+ const packageJsonPath = path.join(appRoot, "package.json");
50
+ const packageJson = (await pathExists(packageJsonPath))
51
+ ? JSON.parse(await readFile(packageJsonPath, "utf8"))
52
+ : { name: "fixture-app", private: true, type: "module" };
53
+ packageJson.dependencies = { ...(packageJson.dependencies || {}) };
54
+
55
+ for (const [packageId, options] of Object.entries(packages)) {
56
+ const packagePath = String(options?.packagePath || "").trim();
57
+ const packageRoot = packagePath
58
+ ? path.join(appRoot, packagePath)
59
+ : path.join(appRoot, "node_modules", ...packageId.split("/"));
60
+ packageJson.dependencies[packageId] = packagePath ? `file:${packagePath}` : "1.0.0";
61
+ await mkdir(packageRoot, { recursive: true });
62
+ const installedPackageJsonPath = path.join(packageRoot, "package.json");
63
+ if (!(await pathExists(installedPackageJsonPath))) {
64
+ await writeJson(installedPackageJsonPath, {
65
+ name: packageId,
66
+ version: "1.0.0",
67
+ exports: options?.exports || {}
68
+ });
60
69
  }
61
- });
70
+ if (!JSON.parse(await readFile(installedPackageJsonPath, "utf8")).jskit) {
71
+ await writePackageMetadata(packageRoot, {
72
+ packageId,
73
+ version: "1.0.0"
74
+ });
75
+ }
76
+ }
77
+
78
+ await writeJson(packageJsonPath, packageJson);
79
+ }
62
80
 
63
- const localPackages = await resolveLocalPackageSources({
64
- appRoot: tempRoot,
65
- lockPath: ".jskit/lock.json"
81
+ test("resolveLocalPackageSources includes every file dependency regardless of scope or exports", async () => {
82
+ const tempRoot = await mkdtemp(path.join(os.tmpdir(), "jskit-client-bootstrap-local-resolution-"));
83
+ await declareInstalledPackages(tempRoot, {
84
+ "@local/main": { packagePath: "packages/main" },
85
+ "@local/feature": { packagePath: "packages/feature" },
86
+ "@example/local-utility": { packagePath: "packages/utility" },
87
+ "@example/published": {}
66
88
  });
89
+
90
+ const localPackages = await resolveLocalPackageSources({ appRoot: tempRoot });
67
91
  assert.deepEqual(localPackages.map((entry) => entry.packageId), [
68
92
  "@example/local-utility",
69
93
  "@local/feature",
@@ -110,22 +134,22 @@ test("createVirtualModuleSource renders deterministic client module imports", ()
110
134
  const source = createVirtualModuleSource([
111
135
  {
112
136
  packageId: "@z/pkg",
113
- descriptorUiRoutes: [{ id: "z.route", path: "/z", scope: "global", componentKey: "z-view" }],
114
- descriptorClientProviders: [{ export: "ZProvider", entrypoint: "src/client/providers/ZProvider.js" }]
137
+ packageMetadataUiRoutes: [{ id: "z.route", path: "/z", scope: "global", componentKey: "z-view" }],
138
+ packageMetadataClientProviders: [{ export: "ZProvider", entrypoint: "src/client/providers/ZProvider.js" }]
115
139
  },
116
140
  {
117
141
  packageId: "@a/pkg",
118
- descriptorUiRoutes: [{ id: "a.route", path: "/a", scope: "global", componentKey: "a-view" }],
119
- descriptorClientProviders: [{ export: "AProvider", entrypoint: "src/client/providers/AProvider.js" }]
142
+ packageMetadataUiRoutes: [{ id: "a.route", path: "/a", scope: "global", componentKey: "a-view" }],
143
+ packageMetadataClientProviders: [{ export: "AProvider", entrypoint: "src/client/providers/AProvider.js" }]
120
144
  }
121
145
  ]);
122
146
 
123
147
  assert.match(source, /import \* as clientModule0 from "@a\/pkg\/client";/);
124
148
  assert.match(source, /import \* as clientModule1 from "@z\/pkg\/client";/);
125
- assert.match(source, /descriptorUiRoutes: \[\{"id":"a\.route","path":"\/a","scope":"global","componentKey":"a-view"\}\]/);
126
- assert.match(source, /descriptorClientProviders: \[\{"export":"AProvider","entrypoint":"src\/client\/providers\/AProvider\.js"\}\]/);
127
- assert.match(source, /descriptorUiRoutes: \[\{"id":"z\.route","path":"\/z","scope":"global","componentKey":"z-view"\}\]/);
128
- assert.match(source, /descriptorClientProviders: \[\{"export":"ZProvider","entrypoint":"src\/client\/providers\/ZProvider\.js"\}\]/);
149
+ assert.match(source, /packageMetadataUiRoutes: \[\{"id":"a\.route","path":"\/a","scope":"global","componentKey":"a-view"\}\]/);
150
+ assert.match(source, /packageMetadataClientProviders: \[\{"export":"AProvider","entrypoint":"src\/client\/providers\/AProvider\.js"\}\]/);
151
+ assert.match(source, /packageMetadataUiRoutes: \[\{"id":"z\.route","path":"\/z","scope":"global","componentKey":"z-view"\}\]/);
152
+ assert.match(source, /packageMetadataClientProviders: \[\{"export":"ZProvider","entrypoint":"src\/client\/providers\/ZProvider\.js"\}\]/);
129
153
  assert.match(source, /bootClientModules/);
130
154
  assert.match(source, /installedClientModules/);
131
155
  });
@@ -135,22 +159,22 @@ test("resolveClientOptimizeExcludeSpecifiers excludes local/app-local package ro
135
159
  {
136
160
  packageId: "@z/pkg",
137
161
  sourceType: "packages-directory",
138
- descriptorUiRoutes: []
162
+ packageMetadataUiRoutes: []
139
163
  },
140
164
  {
141
165
  packageId: "@a/pkg",
142
166
  sourceType: "app-local-package",
143
- descriptorUiRoutes: []
167
+ packageMetadataUiRoutes: []
144
168
  },
145
169
  {
146
170
  packageId: "@b/pkg",
147
171
  sourceType: "local-package",
148
- descriptorUiRoutes: []
172
+ packageMetadataUiRoutes: []
149
173
  },
150
174
  {
151
175
  packageId: "@c/pkg",
152
176
  sourceType: "npm",
153
- descriptorUiRoutes: []
177
+ packageMetadataUiRoutes: []
154
178
  }
155
179
  ]);
156
180
 
@@ -164,19 +188,19 @@ test("resolveClientOptimizeExcludeSpecifiers excludes local/app-local package ro
164
188
  ]);
165
189
  });
166
190
 
167
- test("resolveClientOptimizeExcludeSpecifiers includes descriptor-declared excludes", () => {
191
+ test("resolveClientOptimizeExcludeSpecifiers includes packageMetadata-declared excludes", () => {
168
192
  const exclude = resolveClientOptimizeExcludeSpecifiers([
169
193
  {
170
194
  packageId: "@z/pkg",
171
195
  sourceType: "packages-directory",
172
- descriptorUiRoutes: [],
173
- descriptorClientOptimizeExcludeSpecifiers: ["@z/pkg/client"]
196
+ packageMetadataUiRoutes: [],
197
+ packageMetadataClientOptimizeExcludeSpecifiers: ["@z/pkg/client"]
174
198
  },
175
199
  {
176
200
  packageId: "@a/pkg",
177
201
  sourceType: "local-package",
178
- descriptorUiRoutes: [],
179
- descriptorClientOptimizeExcludeSpecifiers: ["external-problem-dep"]
202
+ packageMetadataUiRoutes: [],
203
+ packageMetadataClientOptimizeExcludeSpecifiers: ["external-problem-dep"]
180
204
  }
181
205
  ]);
182
206
 
@@ -194,22 +218,22 @@ test("resolveClientOptimizeIncludeSpecifiers includes only non-local package cli
194
218
  {
195
219
  packageId: "@z/pkg",
196
220
  sourceType: "packages-directory",
197
- descriptorUiRoutes: []
221
+ packageMetadataUiRoutes: []
198
222
  },
199
223
  {
200
224
  packageId: "@a/pkg",
201
225
  sourceType: "app-local-package",
202
- descriptorUiRoutes: []
226
+ packageMetadataUiRoutes: []
203
227
  },
204
228
  {
205
229
  packageId: "@b/pkg",
206
230
  sourceType: "local-package",
207
- descriptorUiRoutes: []
231
+ packageMetadataUiRoutes: []
208
232
  },
209
233
  {
210
234
  packageId: "@c/pkg",
211
235
  sourceType: "npm",
212
- descriptorUiRoutes: []
236
+ packageMetadataUiRoutes: []
213
237
  }
214
238
  ]);
215
239
 
@@ -222,13 +246,13 @@ test("resolveClientOptimizeIncludeSpecifiers omits excluded package clients", ()
222
246
  {
223
247
  packageId: "@z/pkg",
224
248
  sourceType: "packages-directory",
225
- descriptorUiRoutes: []
249
+ packageMetadataUiRoutes: []
226
250
  },
227
251
  {
228
252
  packageId: "@c/pkg",
229
253
  sourceType: "npm",
230
- descriptorUiRoutes: [],
231
- descriptorClientOptimizeIncludeSpecifiers: ["extra-dep"]
254
+ packageMetadataUiRoutes: [],
255
+ packageMetadataClientOptimizeIncludeSpecifiers: ["extra-dep"]
232
256
  }
233
257
  ],
234
258
  ["@z/pkg/client", "extra-dep"]
@@ -253,18 +277,16 @@ test("resolveInstalledClientPackageIds returns only installed packages with a cl
253
277
  const tempRoot = await mkdtemp(path.join(os.tmpdir(), "jskit-client-bootstrap-"));
254
278
  const appRoot = tempRoot;
255
279
 
256
- await mkdir(path.join(appRoot, ".jskit"), { recursive: true });
257
- await writeJson(path.join(appRoot, ".jskit", "lock.json"), {
258
- lockVersion: 1,
259
- installedPackages: {
260
- "@example/has-client": {},
261
- "@example/no-client": {}
262
- }
280
+ await declareInstalledPackages(appRoot, {
281
+ "@example/has-client": {},
282
+ "@example/no-client": {}
263
283
  });
264
284
 
265
285
  await mkdir(path.join(appRoot, "node_modules", "@example", "has-client"), { recursive: true });
266
286
  await writeJson(path.join(appRoot, "node_modules", "@example", "has-client", "package.json"), {
267
287
  name: "@example/has-client",
288
+ version: "1.0.0",
289
+ jskit: { kind: "runtime" },
268
290
  exports: {
269
291
  "./client": "./src/client/index.js"
270
292
  }
@@ -273,15 +295,14 @@ test("resolveInstalledClientPackageIds returns only installed packages with a cl
273
295
  await mkdir(path.join(appRoot, "node_modules", "@example", "no-client"), { recursive: true });
274
296
  await writeJson(path.join(appRoot, "node_modules", "@example", "no-client", "package.json"), {
275
297
  name: "@example/no-client",
298
+ version: "1.0.0",
299
+ jskit: { kind: "runtime" },
276
300
  exports: {
277
301
  "./server": "./src/server/index.js"
278
302
  }
279
303
  });
280
304
 
281
- const packageIds = await resolveInstalledClientPackageIds({
282
- appRoot,
283
- lockPath: ".jskit/lock.json"
284
- });
305
+ const packageIds = await resolveInstalledClientPackageIds({ appRoot });
285
306
 
286
307
  assert.deepEqual(packageIds, ["@example/has-client"]);
287
308
  });
@@ -289,23 +310,20 @@ test("resolveInstalledClientPackageIds returns only installed packages with a cl
289
310
  test("resolveInstalledClientModules returns installed modules with client exports", async () => {
290
311
  const tempRoot = await mkdtemp(path.join(os.tmpdir(), "jskit-client-bootstrap-modules-"));
291
312
 
292
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
293
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
294
- lockVersion: 1,
295
- installedPackages: {
296
- "@example/has-client": {}
297
- }
298
- });
313
+ await declareInstalledPackages(tempRoot, { "@example/has-client": {} });
299
314
 
300
315
  const packageRoot = path.join(tempRoot, "node_modules", "@example", "has-client");
301
316
  await mkdir(packageRoot, { recursive: true });
302
317
  await writeJson(path.join(packageRoot, "package.json"), {
303
318
  name: "@example/has-client",
319
+ version: "1.0.0",
304
320
  exports: {
305
321
  "./client": "./src/client/index.js"
306
322
  }
307
323
  });
308
- await writeDescriptor(path.join(packageRoot, "package.descriptor.mjs"), {
324
+ await writePackageMetadata(packageRoot, {
325
+ packageId: "@example/has-client",
326
+ version: "1.0.0",
309
327
  runtime: {
310
328
  client: {
311
329
  providers: [
@@ -335,50 +353,48 @@ test("resolveInstalledClientModules returns installed modules with client export
335
353
  }
336
354
  }
337
355
  });
338
- const modules = await resolveInstalledClientModules({
339
- appRoot: tempRoot,
340
- lockPath: ".jskit/lock.json"
341
- });
356
+ const modules = await resolveInstalledClientModules({ appRoot: tempRoot });
342
357
 
343
358
  assert.equal(modules.length, 1);
344
359
  assert.equal(modules[0].packageId, "@example/has-client");
345
- assert.equal(modules[0].sourceType, "");
346
- assert.equal(Array.isArray(modules[0].descriptorUiRoutes), true);
347
- assert.equal(modules[0].descriptorUiRoutes.length, 1);
348
- assert.equal(modules[0].descriptorUiRoutes[0].id, "auth.default-login-2");
349
- assert.equal(Array.isArray(modules[0].descriptorClientProviders), true);
350
- assert.equal(modules[0].descriptorClientProviders.length, 1);
351
- assert.equal(modules[0].descriptorClientProviders[0].export, "HasClientProvider");
352
- assert.equal(Array.isArray(modules[0].descriptorClientOptimizeIncludeSpecifiers), true);
353
- assert.deepEqual(modules[0].descriptorClientOptimizeIncludeSpecifiers, ["mime-match"]);
360
+ assert.equal(modules[0].sourceType, "npm-package");
361
+ assert.equal(Array.isArray(modules[0].packageMetadataUiRoutes), true);
362
+ assert.equal(modules[0].packageMetadataUiRoutes.length, 1);
363
+ assert.equal(modules[0].packageMetadataUiRoutes[0].id, "auth.default-login-2");
364
+ assert.equal(Array.isArray(modules[0].packageMetadataClientProviders), true);
365
+ assert.equal(modules[0].packageMetadataClientProviders.length, 1);
366
+ assert.equal(modules[0].packageMetadataClientProviders[0].export, "HasClientProvider");
367
+ assert.equal(Array.isArray(modules[0].packageMetadataClientOptimizeIncludeSpecifiers), true);
368
+ assert.deepEqual(modules[0].packageMetadataClientOptimizeIncludeSpecifiers, ["mime-match"]);
354
369
  });
355
370
 
356
- test("resolveInstalledClientModules resolves descriptor via source.packagePath", async () => {
371
+ test("resolveInstalledClientModules resolves a packageMetadata from a file dependency", async () => {
357
372
  const tempRoot = await mkdtemp(path.join(os.tmpdir(), "jskit-client-bootstrap-package-path-"));
358
373
 
359
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
360
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
361
- lockVersion: 1,
362
- installedPackages: {
363
- "@example/has-client": {
364
- source: {
365
- type: "local-package",
366
- packagePath: "packages/has-client"
367
- }
368
- }
369
- }
374
+ await declareInstalledPackages(tempRoot, {
375
+ "@example/has-client": { packagePath: "packages/has-client" }
370
376
  });
371
377
 
372
378
  const packageRoot = path.join(tempRoot, "node_modules", "@example", "has-client");
373
379
  await mkdir(packageRoot, { recursive: true });
374
380
  await writeJson(path.join(packageRoot, "package.json"), {
375
381
  name: "@example/has-client",
382
+ version: "1.0.0",
376
383
  exports: {
377
384
  "./client": "./src/client/index.js"
378
385
  }
379
386
  });
380
387
  await mkdir(path.join(tempRoot, "packages", "has-client"), { recursive: true });
381
- await writeDescriptor(path.join(tempRoot, "packages", "has-client", "package.descriptor.mjs"), {
388
+ await writeJson(path.join(tempRoot, "packages", "has-client", "package.json"), {
389
+ name: "@example/has-client",
390
+ version: "1.0.0",
391
+ exports: {
392
+ "./client": "./src/client/index.js"
393
+ }
394
+ });
395
+ await writePackageMetadata(path.join(tempRoot, "packages", "has-client"), {
396
+ packageId: "@example/has-client",
397
+ version: "1.0.0",
382
398
  runtime: {
383
399
  client: {
384
400
  providers: [
@@ -404,38 +420,19 @@ test("resolveInstalledClientModules resolves descriptor via source.packagePath",
404
420
  }
405
421
  });
406
422
 
407
- const modules = await resolveInstalledClientModules({
408
- appRoot: tempRoot,
409
- lockPath: ".jskit/lock.json"
410
- });
423
+ const modules = await resolveInstalledClientModules({ appRoot: tempRoot });
411
424
 
412
425
  assert.equal(modules.length, 1);
413
426
  assert.equal(modules[0].packageId, "@example/has-client");
414
427
  assert.equal(modules[0].sourceType, "local-package");
415
- assert.equal(modules[0].descriptorUiRoutes.length, 1);
416
- assert.equal(modules[0].descriptorUiRoutes[0].id, "local.route");
417
- assert.equal(modules[0].descriptorClientProviders.length, 1);
418
- assert.equal(modules[0].descriptorClientProviders[0].export, "LocalClientProvider");
428
+ assert.equal(modules[0].packageMetadataUiRoutes.length, 1);
429
+ assert.equal(modules[0].packageMetadataUiRoutes[0].id, "local.route");
430
+ assert.equal(modules[0].packageMetadataClientProviders.length, 1);
431
+ assert.equal(modules[0].packageMetadataClientProviders[0].export, "LocalClientProvider");
419
432
  });
420
433
 
421
- test("resolveLocalScopePackageIds reads @local packages from lock and package.json", async () => {
434
+ test("resolveLocalScopePackageIds reads @local packages from package.json", async () => {
422
435
  const tempRoot = await mkdtemp(path.join(os.tmpdir(), "jskit-client-bootstrap-local-scope-"));
423
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
424
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
425
- lockVersion: 1,
426
- installedPackages: {
427
- "@local/main": {
428
- source: {
429
- type: "packages-directory"
430
- }
431
- },
432
- "@example/remote": {
433
- source: {
434
- type: "packages-directory"
435
- }
436
- }
437
- }
438
- });
439
436
  await writeJson(path.join(tempRoot, "package.json"), {
440
437
  name: "fixture-app",
441
438
  dependencies: {
@@ -447,12 +444,9 @@ test("resolveLocalScopePackageIds reads @local packages from lock and package.js
447
444
  }
448
445
  });
449
446
 
450
- const packageIds = await resolveLocalScopePackageIds({
451
- appRoot: tempRoot,
452
- lockPath: ".jskit/lock.json"
453
- });
447
+ const packageIds = await resolveLocalScopePackageIds({ appRoot: tempRoot });
454
448
 
455
- assert.deepEqual(packageIds, ["@local/dev-only", "@local/feature", "@local/main"]);
449
+ assert.deepEqual(packageIds, ["@local/dev-only", "@local/feature"]);
456
450
  });
457
451
 
458
452
  test("createJskitClientBootstrapPlugin resolves and loads virtual module", async () => {
@@ -460,22 +454,14 @@ test("createJskitClientBootstrapPlugin resolves and loads virtual module", async
460
454
  const previousCwd = process.cwd();
461
455
 
462
456
  try {
463
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
464
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
465
- lockVersion: 1,
466
- installedPackages: {
467
- "@example/has-client": {
468
- source: {
469
- type: "packages-directory"
470
- }
471
- }
472
- }
473
- });
457
+ await declareInstalledPackages(tempRoot, { "@example/has-client": {} });
474
458
 
475
459
  const packageRoot = path.join(tempRoot, "node_modules", "@example", "has-client");
476
460
  await mkdir(packageRoot, { recursive: true });
477
461
  await writeJson(path.join(packageRoot, "package.json"), {
478
462
  name: "@example/has-client",
463
+ version: "1.0.0",
464
+ jskit: { kind: "runtime" },
479
465
  exports: {
480
466
  "./client": "./src/client/index.js"
481
467
  }
@@ -499,34 +485,11 @@ test("createJskitClientBootstrapPlugin resolves multiple local packages before V
499
485
  const previousCwd = process.cwd();
500
486
 
501
487
  try {
502
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
503
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
504
- lockVersion: 1,
505
- installedPackages: {
506
- "@local/main": {
507
- source: {
508
- type: "local-package",
509
- packagePath: "packages/main"
510
- }
511
- },
512
- "@local/feature": {
513
- source: {
514
- type: "app-local-package",
515
- packagePath: "packages/feature"
516
- }
517
- },
518
- "@example/local-utility": {
519
- source: {
520
- type: "local-package",
521
- packagePath: "packages/utility"
522
- }
523
- },
524
- "@example/published": {
525
- source: {
526
- type: "npm"
527
- }
528
- }
529
- }
488
+ await declareInstalledPackages(tempRoot, {
489
+ "@local/main": { packagePath: "packages/main" },
490
+ "@local/feature": { packagePath: "packages/feature" },
491
+ "@example/local-utility": { packagePath: "packages/utility" },
492
+ "@example/published": {}
530
493
  });
531
494
 
532
495
  const packageFixtures = [
@@ -558,6 +521,7 @@ test("createJskitClientBootstrapPlugin resolves multiple local packages before V
558
521
  for (const fixture of packageFixtures) {
559
522
  const packageJson = {
560
523
  name: fixture.packageId,
524
+ version: "1.0.0",
561
525
  exports: fixture.exports
562
526
  };
563
527
  const sourcePackageRoot = path.join(tempRoot, "packages", fixture.packageDirectory);
@@ -566,12 +530,17 @@ test("createJskitClientBootstrapPlugin resolves multiple local packages before V
566
530
  await mkdir(installedPackageRoot, { recursive: true });
567
531
  await writeJson(path.join(sourcePackageRoot, "package.json"), packageJson);
568
532
  await writeJson(path.join(installedPackageRoot, "package.json"), packageJson);
533
+ await writePackageMetadata(sourcePackageRoot, {
534
+ packageId: fixture.packageId,
535
+ version: "1.0.0"
536
+ });
569
537
  }
570
538
 
571
539
  const publishedPackageRoot = path.join(tempRoot, "node_modules", "@example", "published");
572
540
  await mkdir(publishedPackageRoot, { recursive: true });
573
541
  await writeJson(path.join(publishedPackageRoot, "package.json"), {
574
542
  name: "@example/published",
543
+ version: "1.0.0",
575
544
  exports: {
576
545
  "./client": "./src/client/index.js"
577
546
  }
@@ -635,22 +604,14 @@ test("createJskitClientBootstrapPlugin config excludes installed client package
635
604
  const previousCwd = process.cwd();
636
605
 
637
606
  try {
638
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
639
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
640
- lockVersion: 1,
641
- installedPackages: {
642
- "@example/has-client": {
643
- source: {
644
- type: "packages-directory"
645
- }
646
- }
647
- }
648
- });
607
+ await declareInstalledPackages(tempRoot, { "@example/has-client": {} });
649
608
 
650
609
  const packageRoot = path.join(tempRoot, "node_modules", "@example", "has-client");
651
610
  await mkdir(packageRoot, { recursive: true });
652
611
  await writeJson(path.join(packageRoot, "package.json"), {
653
612
  name: "@example/has-client",
613
+ version: "1.0.0",
614
+ jskit: { kind: "runtime" },
654
615
  exports: {
655
616
  "./client": "./src/client/index.js"
656
617
  }
@@ -674,32 +635,25 @@ test("createJskitClientBootstrapPlugin config excludes installed client package
674
635
  }
675
636
  });
676
637
 
677
- test("createJskitClientBootstrapPlugin config lets descriptor excludes override automatic client includes", async () => {
678
- const tempRoot = await mkdtemp(path.join(os.tmpdir(), "jskit-client-bootstrap-config-descriptor-exclude-"));
638
+ test("createJskitClientBootstrapPlugin config lets packageMetadata excludes override automatic client includes", async () => {
639
+ const tempRoot = await mkdtemp(path.join(os.tmpdir(), "jskit-client-bootstrap-config-packageMetadata-exclude-"));
679
640
  const previousCwd = process.cwd();
680
641
 
681
642
  try {
682
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
683
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
684
- lockVersion: 1,
685
- installedPackages: {
686
- "@example/app-bound-client": {
687
- source: {
688
- type: "npm"
689
- }
690
- }
691
- }
692
- });
643
+ await declareInstalledPackages(tempRoot, { "@example/app-bound-client": {} });
693
644
 
694
645
  const packageRoot = path.join(tempRoot, "node_modules", "@example", "app-bound-client");
695
646
  await mkdir(packageRoot, { recursive: true });
696
647
  await writeJson(path.join(packageRoot, "package.json"), {
697
648
  name: "@example/app-bound-client",
649
+ version: "1.0.0",
698
650
  exports: {
699
651
  "./client": "./src/client/index.js"
700
652
  }
701
653
  });
702
- await writeDescriptor(path.join(packageRoot, "package.descriptor.mjs"), {
654
+ await writePackageMetadata(packageRoot, {
655
+ packageId: "@example/app-bound-client",
656
+ version: "1.0.0",
703
657
  metadata: {
704
658
  client: {
705
659
  optimizeDeps: {
@@ -731,32 +685,23 @@ test("createJskitClientBootstrapPlugin config excludes local package roots and c
731
685
  const previousCwd = process.cwd();
732
686
 
733
687
  try {
734
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
735
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
736
- lockVersion: 1,
737
- installedPackages: {
738
- "@example/local-client": {
739
- source: {
740
- type: "local-package"
741
- }
742
- },
743
- "@example/remote-client": {
744
- source: {
745
- type: "packages-directory"
746
- }
747
- }
748
- }
688
+ await declareInstalledPackages(tempRoot, {
689
+ "@example/local-client": { packagePath: "packages/local-client" },
690
+ "@example/remote-client": {}
749
691
  });
750
692
 
751
- const localPackageRoot = path.join(tempRoot, "node_modules", "@example", "local-client");
693
+ const localPackageRoot = path.join(tempRoot, "packages", "local-client");
752
694
  await mkdir(localPackageRoot, { recursive: true });
753
695
  await writeJson(path.join(localPackageRoot, "package.json"), {
754
696
  name: "@example/local-client",
697
+ version: "1.0.0",
755
698
  exports: {
756
699
  "./client": "./src/client/index.js"
757
700
  }
758
701
  });
759
- await writeDescriptor(path.join(localPackageRoot, "package.descriptor.mjs"), {
702
+ await writePackageMetadata(localPackageRoot, {
703
+ packageId: "@example/local-client",
704
+ version: "1.0.0",
760
705
  metadata: {
761
706
  client: {
762
707
  optimizeDeps: {
@@ -770,6 +715,8 @@ test("createJskitClientBootstrapPlugin config excludes local package roots and c
770
715
  await mkdir(remotePackageRoot, { recursive: true });
771
716
  await writeJson(path.join(remotePackageRoot, "package.json"), {
772
717
  name: "@example/remote-client",
718
+ version: "1.0.0",
719
+ jskit: { kind: "runtime" },
773
720
  exports: {
774
721
  "./client": "./src/client/index.js"
775
722
  }
@@ -796,10 +743,10 @@ test("createJskitClientBootstrapPlugin config preserves user resolve fields and
796
743
  const previousCwd = process.cwd();
797
744
 
798
745
  try {
799
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
800
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
801
- lockVersion: 1,
802
- installedPackages: {}
746
+ await writeJson(path.join(tempRoot, "package.json"), {
747
+ name: "fixture-app",
748
+ private: true,
749
+ type: "module"
803
750
  });
804
751
 
805
752
  process.chdir(tempRoot);
@@ -822,39 +769,31 @@ test("createJskitClientBootstrapPlugin config preserves user resolve fields and
822
769
  }
823
770
  });
824
771
 
825
- test("createJskitClientBootstrapPlugin config excludes all @local scoped packages from lock and package.json", async () => {
772
+ test("createJskitClientBootstrapPlugin config excludes all @local scoped packages from package.json", async () => {
826
773
  const tempRoot = await mkdtemp(path.join(os.tmpdir(), "jskit-client-bootstrap-local-scope-config-"));
827
774
  const previousCwd = process.cwd();
828
775
 
829
776
  try {
830
- await mkdir(path.join(tempRoot, ".jskit"), { recursive: true });
831
- await writeJson(path.join(tempRoot, ".jskit", "lock.json"), {
832
- lockVersion: 1,
833
- installedPackages: {
834
- "@local/main": {
835
- source: {
836
- type: "packages-directory"
837
- }
838
- },
839
- "@example/remote-client": {
840
- source: {
841
- type: "packages-directory"
842
- }
843
- }
844
- }
845
- });
846
777
  await writeJson(path.join(tempRoot, "package.json"), {
847
778
  name: "fixture-app",
848
779
  dependencies: {
780
+ "@local/main": "file:packages/main",
849
781
  "@local/feature": "file:packages/feature",
850
782
  "@example/remote-client": "^1.0.0"
851
783
  }
852
784
  });
785
+ await declareInstalledPackages(tempRoot, {
786
+ "@local/main": { packagePath: "packages/main" },
787
+ "@local/feature": { packagePath: "packages/feature" },
788
+ "@example/remote-client": {}
789
+ });
853
790
 
854
791
  const remotePackageRoot = path.join(tempRoot, "node_modules", "@example", "remote-client");
855
792
  await mkdir(remotePackageRoot, { recursive: true });
856
793
  await writeJson(path.join(remotePackageRoot, "package.json"), {
857
794
  name: "@example/remote-client",
795
+ version: "1.0.0",
796
+ jskit: { kind: "runtime" },
858
797
  exports: {
859
798
  "./client": "./src/client/index.js"
860
799
  }