@savvy-web/silk-effects 3.0.3 → 3.1.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.
@@ -237,15 +237,16 @@ function makeShape(inspector) {
237
237
  path,
238
238
  status: "added"
239
239
  }));
240
+ const isOwnChangeset = (path) => path.startsWith(".changeset/") && path.endsWith(".md");
240
241
  const seen = /* @__PURE__ */ new Set();
241
242
  const rawEntries = [];
242
243
  for (const e of diffEntries) {
243
- if (seen.has(e.path)) continue;
244
+ if (seen.has(e.path) || isOwnChangeset(e.path)) continue;
244
245
  seen.add(e.path);
245
246
  rawEntries.push(e);
246
247
  }
247
248
  for (const e of untrackedEntries) {
248
- if (seen.has(e.path)) continue;
249
+ if (seen.has(e.path) || isOwnChangeset(e.path)) continue;
249
250
  seen.add(e.path);
250
251
  rawEntries.push(e);
251
252
  }
@@ -257,7 +257,8 @@ function makeShape(pit, inspector, discovery, detector, config, fs) {
257
257
  fromRef = yield* gitMergeBase(resolvedCwd, baseBranch);
258
258
  }
259
259
  const rawDiffs = computeWorkspaceDependencyDiffs(yield* pit.at(fromRef, { cwd: resolvedCwd }), options.to ? yield* pit.at(options.to, { cwd: resolvedCwd }) : yield* pit.worktree({ cwd: resolvedCwd }));
260
- const targetPkg = options.package;
260
+ const explicitTargets = /* @__PURE__ */ new Set([...options.packages ?? [], ...options.package ? [options.package] : []]);
261
+ const excluded = new Set(options.exclude ?? []);
261
262
  const livePackages = yield* discovery.listPackages(resolvedCwd);
262
263
  const publishable = yield* listPublishablePackageNames(livePackages, resolvedCwd).pipe(Effect.provide(provideDetector));
263
264
  const versionPrivate = yield* config.versionPrivate(resolvedCwd);
@@ -266,9 +267,15 @@ function makeShape(pit, inspector, discovery, detector, config, fs) {
266
267
  if (yield* config.isIgnored(pkg.name, resolvedCwd)) continue;
267
268
  if (publishable.has(pkg.name) || versionPrivate) inScope.add(pkg.name);
268
269
  }
269
- const targetIgnored = targetPkg ? yield* config.isIgnored(targetPkg, resolvedCwd) : false;
270
+ const activeTargets = /* @__PURE__ */ new Set();
271
+ for (const name of explicitTargets) {
272
+ if (excluded.has(name)) continue;
273
+ if (yield* config.isIgnored(name, resolvedCwd)) continue;
274
+ activeTargets.add(name);
275
+ }
276
+ const inScopeFor = (name) => explicitTargets.size > 0 ? activeTargets.has(name) : inScope.has(name) && !excluded.has(name);
270
277
  const keepDevDeps = options.includeDevDeps === true;
271
- const scoped = targetPkg ? targetIgnored ? [] : rawDiffs.filter((d) => d.package === targetPkg) : rawDiffs.filter((d) => inScope.has(d.package));
278
+ const scoped = rawDiffs.filter((d) => inScopeFor(d.package));
272
279
  const resolved = [];
273
280
  for (const diff of scoped) {
274
281
  const rows = keepDevDeps ? [...diff.rows] : diff.rows.filter((r) => r.type !== "devDependency");
@@ -279,7 +286,7 @@ function makeShape(pit, inspector, discovery, detector, config, fs) {
279
286
  }
280
287
  const existingPure = yield* findPureDependencyChangesets(fs, changesetDir);
281
288
  const skippedMixed = yield* findMixedDependencyChangesets(fs, changesetDir);
282
- const toDelete = targetPkg ? targetIgnored ? [] : existingPure.filter((p) => p.package === targetPkg) : existingPure.filter((p) => inScope.has(p.package));
289
+ const toDelete = existingPure.filter((p) => inScopeFor(p.package));
283
290
  const chosenFilenames = /* @__PURE__ */ new Set();
284
291
  const toWrite = [];
285
292
  for (const diff of resolved) {
@@ -43,6 +43,32 @@ const DEP_TYPE_MAP = [
43
43
  */
44
44
  const resolveOrRaw = (snapshot, dep, spec) => Option.getOrElse(snapshot.resolve(dep, spec), () => spec);
45
45
  /**
46
+ * Drop no-net-change field moves: the same dependency removed from one field
47
+ * and added to another with an equal resolved version (e.g. a dep promoted
48
+ * from `devDependencies` to `dependencies`). A field reclassification is a
49
+ * contract change worth release-note prose, not a version movement, so it
50
+ * must not surface as an unrelated removed row plus an added row. Moves that
51
+ * also change the resolved version keep both rows (the movement is real).
52
+ */
53
+ const collapseFieldMoves = (rows) => {
54
+ const dropped = /* @__PURE__ */ new Set();
55
+ const byName = /* @__PURE__ */ new Map();
56
+ for (const row of rows) {
57
+ const group = byName.get(row.dependency);
58
+ if (group) group.push(row);
59
+ else byName.set(row.dependency, [row]);
60
+ }
61
+ for (const group of byName.values()) for (const removed of group) {
62
+ if (removed.action !== "removed" || dropped.has(removed)) continue;
63
+ const added = group.find((r) => r.action === "added" && !dropped.has(r) && r.type !== removed.type && r.to === removed.from);
64
+ if (added) {
65
+ dropped.add(removed);
66
+ dropped.add(added);
67
+ }
68
+ }
69
+ return rows.filter((r) => !dropped.has(r));
70
+ };
71
+ /**
46
72
  * Diff two workspace snapshots and return per-package dependency-table rows,
47
73
  * comparing already-resolved specifier values per side.
48
74
  *
@@ -98,10 +124,11 @@ function computeWorkspaceDependencyDiffs(before, after) {
98
124
  });
99
125
  }
100
126
  }
101
- if (rows.length > 0) result.push({
127
+ const collapsed = collapseFieldMoves(rows);
128
+ if (collapsed.length > 0) result.push({
102
129
  package: afterPkg.name,
103
130
  relativePath: afterPkg.relativePath,
104
- rows: sortDependencyRows(rows)
131
+ rows: sortDependencyRows(collapsed)
105
132
  });
106
133
  }
107
134
  return result;
package/index.d.ts CHANGED
@@ -3766,8 +3766,20 @@ interface DepsRegenOptions {
3766
3766
  readonly cwd: string;
3767
3767
  /** Override the base branch used to compute the merge-base when `from` is omitted. */
3768
3768
  readonly base?: string;
3769
- /** Restrict regeneration to a single workspace package. */
3769
+ /** Restrict regeneration to a single workspace package. Unioned with {@link DepsRegenOptions.packages}. */
3770
3770
  readonly package?: string;
3771
+ /**
3772
+ * Restrict regeneration to these workspace packages. Like `package`, an
3773
+ * explicit target bypasses the versionable gate but NOT the changeset
3774
+ * ignore list. Unioned with `package` when both are set.
3775
+ */
3776
+ readonly packages?: ReadonlyArray<string>;
3777
+ /**
3778
+ * Drop these packages from scope entirely — no changesets are written for
3779
+ * them and none of their stale pure-dependency changesets are deleted.
3780
+ * Applies to both repo-wide and explicitly-targeted runs (exclude wins).
3781
+ */
3782
+ readonly exclude?: ReadonlyArray<string>;
3771
3783
  /**
3772
3784
  * When `true`, retain `devDependency` rows (the `deps detect` path);
3773
3785
  * when falsy (the `deps regen` default), drop them unconditionally.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvy-web/silk-effects",
3
- "version": "3.0.3",
3
+ "version": "3.1.0",
4
4
  "private": false,
5
5
  "description": "Shared Effect library for Silk Suite conventions",
6
6
  "homepage": "https://github.com/savvy-web/systems/tree/main/packages/silk-effects",