@effected/workspaces 0.30.4 → 0.32.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/DependencyGraph.js +17 -7
- package/DuplicateCheck.js +8 -7
- package/LayerPolicy.js +1 -1
- package/LockfileReader.js +4 -1
- package/PackageManagerName.js +3 -4
- package/PackedInstall.js +135 -15
- package/PeerCheck.js +6 -2
- package/Publishability.js +10 -14
- package/README.md +4 -4
- package/ReleaseTag.js +6 -5
- package/SourceBoundary.js +1 -1
- package/VersioningStrategy.js +14 -4
- package/WorkspaceCatalogs.js +3 -4
- package/WorkspaceDiscovery.js +7 -7
- package/WorkspacePackage.js +16 -12
- package/WorkspaceRoot.js +4 -6
- package/WorkspaceSnapshots.js +4 -1
- package/WorkspaceStateSnapshot.js +10 -16
- package/Workspaces.js +13 -17
- package/WorkspacesSync.js +1 -3
- package/index.d.ts +152 -146
- package/internal/importerVersions.js +1 -1
- package/node-sync.d.ts +2 -0
- package/package.json +12 -12
- package/testing.d.ts +179 -47
package/WorkspacePackage.js
CHANGED
|
@@ -119,13 +119,9 @@ var WorkspacePackage = class WorkspacePackage extends Schema.Class("WorkspacePac
|
|
|
119
119
|
* Absolute path to the workspace root this package was discovered under.
|
|
120
120
|
*
|
|
121
121
|
* @remarks
|
|
122
|
-
* Carried, not derived
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* root arithmetic (counting `relativePath` segments and re-ascending that
|
|
126
|
-
* many `..`). That reconstruction is exact only while `path` and
|
|
127
|
-
* `relativePath` agree, and it re-derives something the kit never had to
|
|
128
|
-
* lose.
|
|
122
|
+
* Carried, not derived: `WorkspaceDiscovery` resolves the root before
|
|
123
|
+
* enumerating, so every package arrives with it and consumers need no
|
|
124
|
+
* per-package root arithmetic over `relativePath`.
|
|
129
125
|
*
|
|
130
126
|
* For the root package this equals `path`, and `relativePath` is `"."`.
|
|
131
127
|
*/
|
|
@@ -152,8 +148,7 @@ var WorkspacePackage = class WorkspacePackage extends Schema.Class("WorkspacePac
|
|
|
152
148
|
* validated beyond being a record. For the strict typed model use
|
|
153
149
|
* `manifest()`, which deliberately **re-reads** the file — a point-in-time
|
|
154
150
|
* refresh this captured record cannot provide. Defaults to `{}` for
|
|
155
|
-
*
|
|
156
|
-
* field.
|
|
151
|
+
* values constructed or decoded without the field.
|
|
157
152
|
*/
|
|
158
153
|
manifestRecord: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_MANIFEST)), Schema.withConstructorDefault(Effect.succeed(EMPTY_MANIFEST)))
|
|
159
154
|
}) {
|
|
@@ -218,8 +213,8 @@ var WorkspacePackage = class WorkspacePackage extends Schema.Class("WorkspacePac
|
|
|
218
213
|
return version === void 0 ? Option.none() : Option.some(version);
|
|
219
214
|
}
|
|
220
215
|
/**
|
|
221
|
-
* Whether any dependency name
|
|
222
|
-
*
|
|
216
|
+
* Whether any dependency name (across all four kinds) matches the glob
|
|
217
|
+
* `pattern`, using `@effected/glob`.
|
|
223
218
|
*
|
|
224
219
|
* @remarks
|
|
225
220
|
* A `GlobPattern` is total and free to test. A `string` is compiled on every
|
|
@@ -235,7 +230,12 @@ var WorkspacePackage = class WorkspacePackage extends Schema.Class("WorkspacePac
|
|
|
235
230
|
const compiled = typeof pattern === "string" ? GlobPattern.make({ source: pattern }) : pattern;
|
|
236
231
|
return Object.keys(this.allDependencies).some((dependency) => compiled.matches(dependency));
|
|
237
232
|
}
|
|
238
|
-
/**
|
|
233
|
+
/**
|
|
234
|
+
* Compare this package's dependencies against `other`'s, treating `other` as
|
|
235
|
+
* the baseline: what this package added, removed or re-specified.
|
|
236
|
+
*
|
|
237
|
+
* @param other - The package to compare against.
|
|
238
|
+
*/
|
|
239
239
|
dependencyDiff(other) {
|
|
240
240
|
const mine = this.allDependencies;
|
|
241
241
|
const theirs = other.allDependencies;
|
|
@@ -271,6 +271,10 @@ var WorkspacePackage = class WorkspacePackage extends Schema.Class("WorkspacePac
|
|
|
271
271
|
* Read and decode this package's `package.json` into the strict
|
|
272
272
|
* `@effected/package-json` `Package` model — the bridge from the
|
|
273
273
|
* tolerant discovery projection to the fully typed manifest.
|
|
274
|
+
*
|
|
275
|
+
* @remarks
|
|
276
|
+
* Fails with {@link WorkspaceManifestError} (`kind: "read"` or `"decode"`) and
|
|
277
|
+
* requires core `FileSystem`.
|
|
274
278
|
*/
|
|
275
279
|
static manifest = Effect.fn("WorkspacePackage.manifest")(function* (self) {
|
|
276
280
|
const content = yield* (yield* FileSystem.FileSystem).readFileString(self.packageJsonPath).pipe(Effect.mapError((cause) => new WorkspaceManifestError({
|
package/WorkspaceRoot.js
CHANGED
|
@@ -127,12 +127,10 @@ var WorkspaceRoot = class WorkspaceRoot extends Context.Service()("@effected/wor
|
|
|
127
127
|
* A test double resolving every `find` to `root`, with no filesystem.
|
|
128
128
|
*
|
|
129
129
|
* @remarks
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* call pass under test and fail against the live service, which is the
|
|
135
|
-
* failure mode the option exists to catch. A `root` above the ceiling fails
|
|
130
|
+
* Stands in for a hand-written `Layer.succeed` over a `find` that ignores its
|
|
131
|
+
* arguments. Unlike that, this double **honours `stopAt`**: a `find` that
|
|
132
|
+
* ignores the ceiling makes a bounded call pass under test and fail against
|
|
133
|
+
* the live service, which is the failure mode the option exists to catch. A `root` above the ceiling fails
|
|
136
134
|
* here exactly as it would live, with the same
|
|
137
135
|
* {@link WorkspaceRootNotFoundError}.
|
|
138
136
|
*
|
package/WorkspaceSnapshots.js
CHANGED
|
@@ -250,11 +250,14 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends Context.Service()("@ef
|
|
|
250
250
|
};
|
|
251
251
|
});
|
|
252
252
|
/**
|
|
253
|
-
* The live layer
|
|
253
|
+
* The live layer, reading workspace state at a git ref or from the live
|
|
254
|
+
* worktree.
|
|
254
255
|
*
|
|
255
256
|
* @remarks
|
|
256
257
|
* Parameterized, so it mints a fresh reference per call — bind it to a
|
|
257
258
|
* `const` and reuse it, or layer memoization does not apply.
|
|
259
|
+
*
|
|
260
|
+
* @param options - Root resolution and the optional `seedCatalogs`.
|
|
258
261
|
*/
|
|
259
262
|
static layer = (options) => Layer.effect(WorkspaceSnapshots, WorkspaceSnapshots.make(options));
|
|
260
263
|
/**
|
|
@@ -12,10 +12,9 @@ const DependencyMap = Schema.Record(Schema.String, Schema.String).pipe(Schema.wi
|
|
|
12
12
|
*
|
|
13
13
|
* @remarks
|
|
14
14
|
* The Type side is a `NonEmptyString`, so `make` rejects `""` outright. The
|
|
15
|
-
* encoded side stays a plain optional string
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* stored value and a fresh capture of the same manifest compare equal.
|
|
15
|
+
* encoded side stays a plain optional string so that a stored value carrying
|
|
16
|
+
* `""` still decodes, to the absent key it meant — a stored value and a fresh
|
|
17
|
+
* capture of the same manifest compare equal.
|
|
19
18
|
*/
|
|
20
19
|
const SnapshotVersion = Schema.optionalKey(Schema.String).pipe(Schema.decodeTo(Schema.optionalKey(Schema.NonEmptyString), SchemaTransformation.transformOptional({
|
|
21
20
|
decode: (encoded) => Option.filter(encoded, (version) => version !== ""),
|
|
@@ -47,8 +46,7 @@ var PackageStateSnapshot = class extends Schema.Class("PackageStateSnapshot")({
|
|
|
47
46
|
* an ordinary pnpm shape. Both capture paths — `WorkspaceSnapshots.at(ref)`
|
|
48
47
|
* and `WorkspaceSnapshots.worktree()` — omit the key for such a member, so
|
|
49
48
|
* the two sides of a diff agree without a placeholder. Never `""`: `make`
|
|
50
|
-
* rejects it, and a
|
|
51
|
-
* sentinel decodes to the absent key.
|
|
49
|
+
* rejects it, and a stored `""` decodes to the absent key.
|
|
52
50
|
*
|
|
53
51
|
* A version-less member is still a member: it appears in `packages` and
|
|
54
52
|
* answers {@link WorkspaceStateSnapshot.package}, but is absent from
|
|
@@ -125,11 +123,9 @@ var WorkspaceStateSnapshot = class WorkspaceStateSnapshot extends Schema.Class("
|
|
|
125
123
|
* lockfile recorded it at this moment.
|
|
126
124
|
*
|
|
127
125
|
* @remarks
|
|
128
|
-
* Defaults to `{}
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* the behavior those older values were captured under. Only pnpm records
|
|
132
|
-
* importer versions; bun and npm yield an empty index.
|
|
126
|
+
* Defaults to `{}` when absent from a stored value; an empty index makes the
|
|
127
|
+
* `catalog:` fallback in {@link WorkspaceStateSnapshot.resolve} inert. Only
|
|
128
|
+
* pnpm records importer versions; bun and npm yield an empty index.
|
|
133
129
|
*/
|
|
134
130
|
importerVersions: Schema.optionalKey(Schema.Record(Schema.String, Schema.Record(Schema.String, Schema.String))),
|
|
135
131
|
/**
|
|
@@ -143,9 +139,8 @@ var WorkspaceStateSnapshot = class WorkspaceStateSnapshot extends Schema.Class("
|
|
|
143
139
|
* diagnostic and off this serializable value. Every fresh read sets the
|
|
144
140
|
* field: `{}` under the no-op layer, which resolves nothing, when the file
|
|
145
141
|
* declares no config dependencies, or on the bun / `package.json` path,
|
|
146
|
-
* where config dependencies do not exist. Absent only when decoding a
|
|
147
|
-
*
|
|
148
|
-
* readable. Carried through `withSeededCatalogs` and `crossSeed`
|
|
142
|
+
* where config dependencies do not exist. Absent only when decoding a stored
|
|
143
|
+
* value that omits it. Carried through `withSeededCatalogs` and `crossSeed`
|
|
149
144
|
* unchanged, like `importerVersions`.
|
|
150
145
|
*/
|
|
151
146
|
hookReplays: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),
|
|
@@ -171,8 +166,7 @@ var WorkspaceStateSnapshot = class WorkspaceStateSnapshot extends Schema.Class("
|
|
|
171
166
|
* replays the ref's own pinned hook and the seed answers only what neither
|
|
172
167
|
* source declared.
|
|
173
168
|
*
|
|
174
|
-
* Defaults to absent, which makes the seed inert
|
|
175
|
-
* every snapshot captured before this field existed.
|
|
169
|
+
* Defaults to absent, which makes the seed inert.
|
|
176
170
|
*/
|
|
177
171
|
seededCatalogs: Schema.optionalKey(CatalogSet)
|
|
178
172
|
}) {
|
package/Workspaces.js
CHANGED
|
@@ -83,10 +83,9 @@ var Workspaces = class {
|
|
|
83
83
|
* `@effected/memfs` volume).
|
|
84
84
|
*
|
|
85
85
|
* **`PublishabilityDetector` is neither provided nor required here.** The
|
|
86
|
-
* composite
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* `R` either. The requirement surfaces in the `R` of each operation that
|
|
86
|
+
* composite supplies no default policy, and — because nothing inside it asks
|
|
87
|
+
* a publishability question — it does not require one in `R` either. The
|
|
88
|
+
* requirement surfaces in the `R` of each operation that
|
|
90
89
|
* asks (`VersioningStrategy.detect`, e.g.), so a program that asks and never
|
|
91
90
|
* wires a detector fails to compile at that operation, and a program that
|
|
92
91
|
* never asks never supplies a publish policy. Wire one explicitly where
|
|
@@ -167,10 +166,9 @@ var Workspaces = class {
|
|
|
167
166
|
* `pnpmfile.cjs` hooks**.
|
|
168
167
|
*
|
|
169
168
|
* @remarks
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* `@savvy-web/silk-effects` did, and the copy this static deletes.
|
|
169
|
+
* `layerWithGit` wires the no-op catalogs layer, so this is the composite to
|
|
170
|
+
* reach for when you want snapshots, git and hook replay together without
|
|
171
|
+
* assembling the service graph by hand.
|
|
174
172
|
*
|
|
175
173
|
* Requirements are unchanged from {@link Workspaces.layerWithGit}: a
|
|
176
174
|
* filesystem, a path service, and core's `ChildProcessSpawner` (behind
|
|
@@ -233,8 +231,7 @@ var Workspaces = class {
|
|
|
233
231
|
* and {@link ConfigDependencyHooks.layerSubprocess}. It exists for the fourth
|
|
234
232
|
* policy: {@link ConfigDependencyHooks.layerFrom}, the hermetic seam, which a
|
|
235
233
|
* snapshot-backed test otherwise cannot reach without rebuilding the whole
|
|
236
|
-
* git graph by hand
|
|
237
|
-
* to delete. The ONE hooks reference is handed to both `WorkspaceCatalogs`
|
|
234
|
+
* git graph by hand. The ONE hooks reference is handed to both `WorkspaceCatalogs`
|
|
238
235
|
* and `WorkspaceSnapshots`, so `at(ref)` and `worktree()` cannot drift on
|
|
239
236
|
* which policy they replay. A hooks layer carrying its own requirement (the
|
|
240
237
|
* subprocess variant's `ChildProcessSpawner`) threads it through to the
|
|
@@ -264,13 +261,11 @@ var Workspaces = class {
|
|
|
264
261
|
* contract: how to run a project-local binary here.
|
|
265
262
|
*
|
|
266
263
|
* @remarks
|
|
267
|
-
* **An inverted contract,
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
* package
|
|
272
|
-
* would drag `npm`, `lockfiles` (pure!) and `package-json` up a tier with
|
|
273
|
-
* it. So `commands` declares the narrow contract and we ship the layer.
|
|
264
|
+
* **An inverted contract, like `@effected/npm`'s `CatalogResolver`.** Tool
|
|
265
|
+
* discovery needs package-manager detection and workspace-root resolution,
|
|
266
|
+
* both of which live here, but `@effected/commands` must not depend on this
|
|
267
|
+
* package. So `commands` declares the narrow `LocalExec` contract and this
|
|
268
|
+
* package ships the layer.
|
|
274
269
|
*
|
|
275
270
|
* **The argv knowledge is not duplicated.** `LocalExec.prefixes(name)` is
|
|
276
271
|
* the one home of the four managers' `exec`/`dlx`/script-runner prefixes;
|
|
@@ -304,6 +299,7 @@ var Workspaces = class {
|
|
|
304
299
|
*
|
|
305
300
|
* @example
|
|
306
301
|
* ```ts
|
|
302
|
+
* import { NodeServices } from "@effect/platform-node";
|
|
307
303
|
* import { ToolDiscovery } from "@effected/commands";
|
|
308
304
|
* import { Workspaces } from "@effected/workspaces";
|
|
309
305
|
* import { Layer } from "effect";
|
package/WorkspacesSync.js
CHANGED
|
@@ -113,9 +113,7 @@ const isPackage = (options, dir) => options.fileSystem.exists(options.path.join(
|
|
|
113
113
|
* The signature is path-first, options second — the same shape as
|
|
114
114
|
* {@link getWorkspacePackagesSync} and the rest of the kit's sync facades
|
|
115
115
|
* (`TsconfigLoaderSync.load(configPath, options)`). `cwd` is required and
|
|
116
|
-
* positional
|
|
117
|
-
* `process.cwd()` read, which both broke the symmetry with its sibling and
|
|
118
|
-
* was the module's one platform assumption.
|
|
116
|
+
* positional, so the function reads no ambient `process.cwd()`.
|
|
119
117
|
*
|
|
120
118
|
* Markers match the async service exactly: a `pnpm-workspace.yaml`, or a
|
|
121
119
|
* `package.json` carrying a `workspaces` field.
|