@smthrs/plan 1.0.0-rc.8 → 1.0.0-rc.9
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/dist/cjs/Effects.d.ts +29 -11
- package/dist/cjs/Effects.d.ts.map +1 -1
- package/dist/cjs/Effects.js.map +2 -2
- package/dist/cjs/FileSet.d.ts +121 -51
- package/dist/cjs/FileSet.d.ts.map +1 -1
- package/dist/cjs/FileSet.js.map +2 -2
- package/dist/cjs/GraphBuildError.d.ts +2 -4
- package/dist/cjs/GraphBuildError.d.ts.map +1 -1
- package/dist/cjs/GraphBuildError.js.map +2 -2
- package/dist/cjs/KeyMaterial.d.ts +13 -8
- package/dist/cjs/KeyMaterial.d.ts.map +1 -1
- package/dist/cjs/KeyMaterial.js.map +2 -2
- package/dist/cjs/Plan.d.ts +72 -23
- package/dist/cjs/Plan.d.ts.map +1 -1
- package/dist/cjs/Plan.js +3 -0
- package/dist/cjs/Plan.js.map +2 -2
- package/dist/cjs/PlanDiff.d.ts +7 -3
- package/dist/cjs/PlanDiff.d.ts.map +1 -1
- package/dist/cjs/PlanDiff.js.map +2 -2
- package/dist/cjs/StepKey.d.ts +38 -17
- package/dist/cjs/StepKey.d.ts.map +1 -1
- package/dist/cjs/StepKey.js.map +2 -2
- package/dist/esm/Effects.d.ts +29 -11
- package/dist/esm/Effects.d.ts.map +1 -1
- package/dist/esm/Effects.js +18 -7
- package/dist/esm/Effects.js.map +1 -1
- package/dist/esm/FileSet.d.ts +121 -51
- package/dist/esm/FileSet.d.ts.map +1 -1
- package/dist/esm/FileSet.js +97 -35
- package/dist/esm/FileSet.js.map +1 -1
- package/dist/esm/GraphBuildError.d.ts +2 -4
- package/dist/esm/GraphBuildError.d.ts.map +1 -1
- package/dist/esm/GraphBuildError.js +2 -3
- package/dist/esm/GraphBuildError.js.map +1 -1
- package/dist/esm/KeyMaterial.d.ts +13 -8
- package/dist/esm/KeyMaterial.d.ts.map +1 -1
- package/dist/esm/KeyMaterial.js +11 -4
- package/dist/esm/KeyMaterial.js.map +1 -1
- package/dist/esm/Plan.d.ts +72 -23
- package/dist/esm/Plan.d.ts.map +1 -1
- package/dist/esm/Plan.js +61 -16
- package/dist/esm/Plan.js.map +1 -1
- package/dist/esm/PlanDiff.d.ts +7 -3
- package/dist/esm/PlanDiff.d.ts.map +1 -1
- package/dist/esm/PlanDiff.js +0 -1
- package/dist/esm/PlanDiff.js.map +1 -1
- package/dist/esm/StepKey.d.ts +38 -17
- package/dist/esm/StepKey.d.ts.map +1 -1
- package/dist/esm/StepKey.js +33 -11
- package/dist/esm/StepKey.js.map +1 -1
- package/docs/guides/diff-two-plans.md +78 -1
- package/package.json +4 -4
- package/src/Effects.ts +29 -11
- package/src/FileSet.ts +121 -51
- package/src/GraphBuildError.ts +2 -4
- package/src/KeyMaterial.ts +13 -8
- package/src/Plan.ts +66 -23
- package/src/PlanDiff.ts +7 -3
- package/src/StepKey.ts +38 -17
package/dist/cjs/Effects.d.ts
CHANGED
|
@@ -118,17 +118,21 @@ export type { PathIndex, PreparedEnvelope, Ranked } from "./internal/effects.ts"
|
|
|
118
118
|
export { boundedEffects, indexPaths, maximumGlobs, maximumPathLength, narrowPrepared, overlapRanks, prepareEnvelope, rankPaths } from "./internal/effects.ts";
|
|
119
119
|
/**
|
|
120
120
|
* A normalized description of the resources a flow or step may read and
|
|
121
|
-
* write.
|
|
121
|
+
* write. Build one with {@link make}.
|
|
122
122
|
*
|
|
123
123
|
* @category models
|
|
124
124
|
* @since 0.0.0
|
|
125
|
-
* @slop
|
|
126
125
|
*/
|
|
127
126
|
export interface Declaration {
|
|
127
|
+
/** Readable paths or envelope patterns, sorted and duplicate-free. */
|
|
128
128
|
readonly reads: ReadonlyArray<string>;
|
|
129
|
+
/** Writable paths or envelope patterns, sorted and duplicate-free. */
|
|
129
130
|
readonly writes: ReadonlyArray<string>;
|
|
131
|
+
/** `hermetic` or `expected` enforcement. */
|
|
130
132
|
readonly mode: Mode;
|
|
133
|
+
/** What a plan does when another node writes an overlapping path. */
|
|
131
134
|
readonly onConflict: ConflictStrategy;
|
|
135
|
+
/** The effect tier. Absent means `sealed`. */
|
|
132
136
|
readonly tier?: Tier | undefined;
|
|
133
137
|
}
|
|
134
138
|
/**
|
|
@@ -141,7 +145,6 @@ export interface Declaration {
|
|
|
141
145
|
*
|
|
142
146
|
* @category models
|
|
143
147
|
* @since 0.0.0
|
|
144
|
-
* @slop
|
|
145
148
|
*/
|
|
146
149
|
export interface MakeOptions {
|
|
147
150
|
readonly reads: Iterable<string>;
|
|
@@ -153,9 +156,13 @@ export interface MakeOptions {
|
|
|
153
156
|
/**
|
|
154
157
|
* A result of checking that a step declaration narrows a flow envelope.
|
|
155
158
|
*
|
|
159
|
+
* On failure, `code` names the first rule broken, checked in this order:
|
|
160
|
+
* `effect_outside_envelope` (with the uncovered read and write paths, sorted),
|
|
161
|
+
* `effect_mode_widening`, then `effect_tier_widening` (both with empty
|
|
162
|
+
* `paths`).
|
|
163
|
+
*
|
|
156
164
|
* @category models
|
|
157
165
|
* @since 0.0.0
|
|
158
|
-
* @slop
|
|
159
166
|
*/
|
|
160
167
|
export type NarrowResult = {
|
|
161
168
|
readonly ok: true;
|
|
@@ -165,11 +172,14 @@ export type NarrowResult = {
|
|
|
165
172
|
readonly paths: ReadonlyArray<string>;
|
|
166
173
|
};
|
|
167
174
|
/**
|
|
168
|
-
* Constructs a deterministic effect declaration
|
|
175
|
+
* Constructs a deterministic effect declaration: `reads` and `writes` are
|
|
176
|
+
* collected, deduplicated, and sorted; an absent `tier` is omitted. Paths are
|
|
177
|
+
* not validated or rewritten.
|
|
169
178
|
*
|
|
179
|
+
* @param input - The paths, mode, conflict strategy, and optional tier.
|
|
180
|
+
* @returns The normalized declaration.
|
|
170
181
|
* @category constructors
|
|
171
182
|
* @since 0.0.0
|
|
172
|
-
* @slop
|
|
173
183
|
*/
|
|
174
184
|
export declare const make: (input: MakeOptions) => Declaration;
|
|
175
185
|
/**
|
|
@@ -183,9 +193,11 @@ export declare const make: (input: MakeOptions) => Declaration;
|
|
|
183
193
|
* covered, so {@link narrow} reports it as `effect_outside_envelope` rather
|
|
184
194
|
* than silently accepting an escape.
|
|
185
195
|
*
|
|
196
|
+
* @param envelope - One envelope entry.
|
|
197
|
+
* @param path - One declared path.
|
|
198
|
+
* @returns `true` when the entry covers the path.
|
|
186
199
|
* @category predicates
|
|
187
200
|
* @since 0.0.0
|
|
188
|
-
* @slop
|
|
189
201
|
*/
|
|
190
202
|
export declare const covers: (envelope: string, path: string) => boolean;
|
|
191
203
|
/**
|
|
@@ -202,9 +214,11 @@ export declare const covers: (envelope: string, path: string) => boolean;
|
|
|
202
214
|
* patterns nest. A graph build prepares each envelope once for every node it
|
|
203
215
|
* encloses.
|
|
204
216
|
*
|
|
217
|
+
* @param envelope - The flow's declaration.
|
|
218
|
+
* @param step - The step's declaration.
|
|
219
|
+
* @returns `{ ok: true }`, or the first rule the step breaks.
|
|
205
220
|
* @category validation
|
|
206
221
|
* @since 0.0.0
|
|
207
|
-
* @slop
|
|
208
222
|
*/
|
|
209
223
|
export declare const narrow: (envelope: Declaration, step: Declaration) => NarrowResult;
|
|
210
224
|
/**
|
|
@@ -224,17 +238,21 @@ export declare const narrow: (envelope: Declaration, step: Declaration) => Narro
|
|
|
224
238
|
* ranks inside its interval, so the cost is linear in the two declarations
|
|
225
239
|
* plus the matches, whatever the paths' lengths or how many patterns nest.
|
|
226
240
|
*
|
|
241
|
+
* @param a - One declaration.
|
|
242
|
+
* @param b - The other declaration.
|
|
243
|
+
* @returns The shared write paths; empty when the writes are disjoint.
|
|
227
244
|
* @category analysis
|
|
228
245
|
* @since 0.0.0
|
|
229
|
-
* @slop
|
|
230
246
|
*/
|
|
231
247
|
export declare const overlaps: (a: Declaration, b: Declaration) => ReadonlyArray<string>;
|
|
232
248
|
/**
|
|
233
|
-
* Returns a sealed, hermetic copy of an effect declaration
|
|
249
|
+
* Returns a sealed, hermetic copy of an effect declaration, normalized by
|
|
250
|
+
* {@link make}. Paths and `onConflict` are kept.
|
|
234
251
|
*
|
|
252
|
+
* @param declaration - The declaration to copy.
|
|
253
|
+
* @returns The copy with `mode: "hermetic"` and `tier: "sealed"`.
|
|
235
254
|
* @category constructors
|
|
236
255
|
* @since 0.0.0
|
|
237
|
-
* @slop
|
|
238
256
|
*/
|
|
239
257
|
export declare const sealed: (declaration: Declaration) => Declaration;
|
|
240
258
|
//# sourceMappingURL=Effects.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Effects.d.ts","sourceRoot":"","sources":["../../src/Effects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,IAAI,qEAA6D,CAAA;AAE9E;;;;;GAKG;AACH,MAAM,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,CAAA;AAEnC;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,oDAA4C,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,CAAA;AAEnC;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,yDAAiD,CAAA;AAE9E;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAA;AAE3D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,2CAAgE,CAAA;AAErF;;;;;;;;;;;;;;;;;;GAkBG;AACH,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAEhF;;;;;;GAMG;AACH,OAAO,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,SAAS,EACV,MAAM,uBAAuB,CAAA;AAE9B
|
|
1
|
+
{"version":3,"file":"Effects.d.ts","sourceRoot":"","sources":["../../src/Effects.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/Effects.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/Effects.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Pure effect declarations used to describe flow read and write envelopes.\n *\n * This is the ONE effect-envelope model. `@smthrs/flow` enforces it while it\n * builds a graph, `@smthrs/core` re-exports it, and `@smthrs/patterns` reads it\n * to intersect a decorator's declaration with the flow it wraps. It lives here\n * because `@smthrs/plan` is the lowest package all three depend on, beside the\n * `tier` and `onConflict` vocabularies a plan already speaks.\n *\n * Two layers: the declaration API, which a flow author and a catalog use, and\n * the prepared matching API below it, which a graph builder uses to check one\n * envelope against many steps without re-reading the envelope each time.\n *\n * Governing contract: `packages/smithers/flows/plan/docs/api.md`, published as\n * https://smithers.sh/docs/reference/api/plan.\n *\n * @since 0.0.0\n */\n\nimport * as Context from \"effect/Context\"\nimport * as Schema from \"effect/Schema\"\nimport * as Index from \"./internal/effects.ts\"\n\n/**\n * How reversible the work beneath a declaration is.\n *\n * This is the ONE tier vocabulary. `KeyMaterial.kind` is this schema, and so\n * is `@smthrs/flow`'s `Action.Tier`: an action's durability and a declared\n * envelope's ceiling are the same three words, and a fourth spelling of them\n * in one of the three places would fork identity silently.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Tier = Schema.Literals([\"sealed\", \"compensable\", \"irreversible\"])\n\n/**\n * The value form of {@link Tier}.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type Tier = typeof Tier.Type\n\n/**\n * How hermetic the work beneath a declaration is.\n *\n * This is the ONE mode vocabulary: the two words were written out in\n * `Declaration`, in `MakeOptions`, and twice more inside the matcher.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Mode = Schema.Literals([\"hermetic\", \"expected\"])\n\n/**\n * The value form of {@link Mode}.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type Mode = typeof Mode.Type\n\n/**\n * What a plan does when two nodes write the same path.\n *\n * This is the ONE conflict vocabulary: `Declaration.onConflict` declares it and\n * `Plan.PairStrategy` is this same schema, resolved per pair by\n * `Plan.compile`.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const ConflictStrategy = Schema.Literals([\"serialize\", \"lane\", \"fail\"])\n\n/**\n * The value form of {@link ConflictStrategy}.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type ConflictStrategy = typeof ConflictStrategy.Type\n\n/**\n * The annotation key a flow's declared effect ENVELOPE is carried under.\n *\n * One key, here, because two graph builders read it: `@smthrs/flow`'s\n * `Graph.build` enforces the envelope it names, and `@smthrs/core` re-exports\n * this key as `Annotations.Effects`. While they were separate keys a flow\n * annotated for one builder was invisible to the other.\n *\n * It is a `Context` key, not hashed material: annotating a flow with an\n * envelope changes what a build ADMITS, and the declaration reaches identity\n * only through `KeyMaterial.kind`.\n *\n * @category annotations\n * @since 1.0.0-rc.0\n */\nexport const Envelope = Context.Service<Declaration>(\"@smthrs/plan/Effects/Envelope\")\n\n/**\n * The prepared matching API: what a graph builder needs to check one envelope\n * against every step it encloses, and to find the write overlaps between two\n * declarations, at the cost the public functions above pay once rather than\n * once per step.\n *\n * {@link prepareEnvelope} reads an envelope once into the form\n * {@link narrowPrepared} answers from, which is what makes a wide envelope cost\n * its size per build rather than per node. {@link indexPaths},\n * {@link rankPaths} and {@link overlapRanks} are the same decomposition for\n * write overlap, which {@link overlaps} wraps for the pairwise case.\n * {@link boundedEffects} snapshots a declaration into builder-owned data,\n * refusing through the caller's own error before the copy grows past its limit,\n * and {@link maximumPathLength} and {@link maximumGlobs} are the per-path bounds\n * that refusal enforces.\n *\n * @category matching\n * @since 1.0.0-rc.0\n */\nexport type { PathIndex, PreparedEnvelope, Ranked } from \"./internal/effects.ts\"\n\n/**\n * The prepared matching API. See the type re-exports above for what each member\n * is for.\n *\n * @category matching\n * @since 1.0.0-rc.0\n */\nexport {\n boundedEffects,\n indexPaths,\n maximumGlobs,\n maximumPathLength,\n narrowPrepared,\n overlapRanks,\n prepareEnvelope,\n rankPaths\n} from \"./internal/effects.ts\"\n\n/**\n * A normalized description of the resources a flow or step may read and\n * write.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport interface Declaration {\n readonly reads: ReadonlyArray<string>\n readonly writes: ReadonlyArray<string>\n readonly mode: Mode\n readonly onConflict: ConflictStrategy\n readonly tier?: Tier | undefined\n}\n\n/**\n * Input accepted by {@link make}. Iterables are normalized into sorted,\n * duplicate-free arrays so declarations are deterministic key material.\n * Envelope entries and declared paths must already be path-normalized: no\n * separator or dot-segment rewriting is performed. A declared path containing\n * a whole `.` or `..` segment is never covered and therefore surfaces from\n * {@link narrow} as an `effect_outside_envelope` diagnostic.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport interface MakeOptions {\n readonly reads: Iterable<string>\n readonly writes: Iterable<string>\n readonly mode: Mode\n readonly onConflict: ConflictStrategy\n readonly tier?: Tier | undefined\n}\n\n/**\n * A result of checking that a step declaration narrows a flow envelope.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport type NarrowResult =\n | { readonly ok: true }\n | {\n readonly ok: false\n readonly code: \"effect_outside_envelope\" | \"effect_mode_widening\" | \"effect_tier_widening\"\n readonly paths: ReadonlyArray<string>\n }\n\nconst normalize = (paths: Iterable<string>): ReadonlyArray<string> => [...new Set(paths)].sort()\n\n/**\n * Constructs a deterministic effect declaration.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const make = (input: MakeOptions): Declaration => ({\n reads: normalize(input.reads),\n writes: normalize(input.writes),\n mode: input.mode,\n onConflict: input.onConflict,\n ...(input.tier === undefined ? {} : { tier: input.tier })\n})\n\n/**\n * Checks whether `path` is covered by an envelope entry.\n *\n * The grammar is exhaustive: an exact path matches itself; `*` and `**` match\n * everything; `prefix*` matches by string prefix; and `prefix/**` matches\n * `prefix/` and everything below it, but not bare `prefix`. This is\n * intentionally not full minimatch syntax. Envelope entries and declared paths\n * must be normalized. A path containing a whole `.` or `..` segment is never\n * covered, so {@link narrow} reports it as `effect_outside_envelope` rather\n * than silently accepting an escape.\n *\n * @category predicates\n * @since 0.0.0\n * @slop\n */\nexport const covers = (envelope: string, path: string): boolean => {\n if (Index.hasDotSegment(path)) return false\n return envelope === path || (Index.isGlob(envelope) && path.startsWith(Index.globPrefix(envelope)))\n}\n\n/**\n * Verifies that a step declaration stays within an enclosing flow envelope.\n *\n * Read and write paths must be covered independently. A step may tighten\n * `expected` to `hermetic`, but cannot widen `hermetic` to `expected`.\n * Effect tiers narrow from irreversible to compensable to sealed.\n *\n * The envelope's lists are prepared once: exact entries go into a set and\n * covering patterns collapse to their outermost prefixes, sorted, so each step\n * path costs one dot-segment scan, one lookup, and one binary search ending in\n * one prefix comparison, whatever the envelope's width or how many of its\n * patterns nest. A graph build prepares each envelope once for every node it\n * encloses.\n *\n * @category validation\n * @since 0.0.0\n * @slop\n */\nexport const narrow = (envelope: Declaration, step: Declaration): NarrowResult =>\n Index.narrowPrepared(Index.prepareEnvelope(envelope), step)\n\n/**\n * Returns the concrete or narrower write declarations shared by two effect\n * declarations. The result is sorted and duplicate-free.\n *\n * Two declarations of the same literal path always overlap, including a path\n * {@link covers} refuses to match because it carries a `.` or `..` segment.\n * Glob coverage stays strict for those paths, so an unnormalized declaration\n * still escapes no envelope, but two writers naming the same unnormalized path\n * are still detected as writing the same resource.\n *\n * The union of both declarations is indexed once: the distinct paths are\n * sorted, each is scanned once for a dot segment, and each pattern's prefix\n * is located by binary search. Exact paths then match through a merge of two\n * rank lists and each covering pattern enumerates the other declaration's\n * ranks inside its interval, so the cost is linear in the two declarations\n * plus the matches, whatever the paths' lengths or how many patterns nest.\n *\n * @category analysis\n * @since 0.0.0\n * @slop\n */\nexport const overlaps = (a: Declaration, b: Declaration): ReadonlyArray<string> => {\n const indexed = Index.indexPaths([a.writes, b.writes])\n return Index.overlapRanks(indexed, Index.rankPaths(indexed, a.writes), Index.rankPaths(indexed, b.writes))\n .map((rank) => indexed.paths[rank]!)\n}\n\n/**\n * Returns a sealed, hermetic copy of an effect declaration.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const sealed = (declaration: Declaration): Declaration =>\n make({ ...declaration, mode: \"hermetic\", tier: \"sealed\" })\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBA,cAAyB;AACzB,aAAwB;AACxB,YAAuB;AA2GvB,qBASO;AAvGA,MAAM,OAAO,OAAO,SAAS,CAAC,UAAU,eAAe,cAAc,CAAC;AAmBtE,MAAM,OAAO,OAAO,SAAS,CAAC,YAAY,UAAU,CAAC;AAoBrD,MAAM,mBAAmB,OAAO,SAAS,CAAC,aAAa,QAAQ,MAAM,CAAC;AAyBtE,MAAM,WAAW,QAAQ,QAAqB,+BAA+B;
|
|
4
|
+
"sourcesContent": ["/**\n * Pure effect declarations used to describe flow read and write envelopes.\n *\n * This is the ONE effect-envelope model. `@smthrs/flow` enforces it while it\n * builds a graph, `@smthrs/core` re-exports it, and `@smthrs/patterns` reads it\n * to intersect a decorator's declaration with the flow it wraps. It lives here\n * because `@smthrs/plan` is the lowest package all three depend on, beside the\n * `tier` and `onConflict` vocabularies a plan already speaks.\n *\n * Two layers: the declaration API, which a flow author and a catalog use, and\n * the prepared matching API below it, which a graph builder uses to check one\n * envelope against many steps without re-reading the envelope each time.\n *\n * Governing contract: `packages/smithers/flows/plan/docs/api.md`, published as\n * https://smithers.sh/docs/reference/api/plan.\n *\n * @since 0.0.0\n */\n\nimport * as Context from \"effect/Context\"\nimport * as Schema from \"effect/Schema\"\nimport * as Index from \"./internal/effects.ts\"\n\n/**\n * How reversible the work beneath a declaration is.\n *\n * This is the ONE tier vocabulary. `KeyMaterial.kind` is this schema, and so\n * is `@smthrs/flow`'s `Action.Tier`: an action's durability and a declared\n * envelope's ceiling are the same three words, and a fourth spelling of them\n * in one of the three places would fork identity silently.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Tier = Schema.Literals([\"sealed\", \"compensable\", \"irreversible\"])\n\n/**\n * The value form of {@link Tier}.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type Tier = typeof Tier.Type\n\n/**\n * How hermetic the work beneath a declaration is.\n *\n * This is the ONE mode vocabulary: the two words were written out in\n * `Declaration`, in `MakeOptions`, and twice more inside the matcher.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Mode = Schema.Literals([\"hermetic\", \"expected\"])\n\n/**\n * The value form of {@link Mode}.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type Mode = typeof Mode.Type\n\n/**\n * What a plan does when two nodes write the same path.\n *\n * This is the ONE conflict vocabulary: `Declaration.onConflict` declares it and\n * `Plan.PairStrategy` is this same schema, resolved per pair by\n * `Plan.compile`.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const ConflictStrategy = Schema.Literals([\"serialize\", \"lane\", \"fail\"])\n\n/**\n * The value form of {@link ConflictStrategy}.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type ConflictStrategy = typeof ConflictStrategy.Type\n\n/**\n * The annotation key a flow's declared effect ENVELOPE is carried under.\n *\n * One key, here, because two graph builders read it: `@smthrs/flow`'s\n * `Graph.build` enforces the envelope it names, and `@smthrs/core` re-exports\n * this key as `Annotations.Effects`. While they were separate keys a flow\n * annotated for one builder was invisible to the other.\n *\n * It is a `Context` key, not hashed material: annotating a flow with an\n * envelope changes what a build ADMITS, and the declaration reaches identity\n * only through `KeyMaterial.kind`.\n *\n * @category annotations\n * @since 1.0.0-rc.0\n */\nexport const Envelope = Context.Service<Declaration>(\"@smthrs/plan/Effects/Envelope\")\n\n/**\n * The prepared matching API: what a graph builder needs to check one envelope\n * against every step it encloses, and to find the write overlaps between two\n * declarations, at the cost the public functions above pay once rather than\n * once per step.\n *\n * {@link prepareEnvelope} reads an envelope once into the form\n * {@link narrowPrepared} answers from, which is what makes a wide envelope cost\n * its size per build rather than per node. {@link indexPaths},\n * {@link rankPaths} and {@link overlapRanks} are the same decomposition for\n * write overlap, which {@link overlaps} wraps for the pairwise case.\n * {@link boundedEffects} snapshots a declaration into builder-owned data,\n * refusing through the caller's own error before the copy grows past its limit,\n * and {@link maximumPathLength} and {@link maximumGlobs} are the per-path bounds\n * that refusal enforces.\n *\n * @category matching\n * @since 1.0.0-rc.0\n */\nexport type { PathIndex, PreparedEnvelope, Ranked } from \"./internal/effects.ts\"\n\n/**\n * The prepared matching API. See the type re-exports above for what each member\n * is for.\n *\n * @category matching\n * @since 1.0.0-rc.0\n */\nexport {\n boundedEffects,\n indexPaths,\n maximumGlobs,\n maximumPathLength,\n narrowPrepared,\n overlapRanks,\n prepareEnvelope,\n rankPaths\n} from \"./internal/effects.ts\"\n\n/**\n * A normalized description of the resources a flow or step may read and\n * write. Build one with {@link make}.\n *\n * @category models\n * @since 0.0.0\n */\nexport interface Declaration {\n /** Readable paths or envelope patterns, sorted and duplicate-free. */\n readonly reads: ReadonlyArray<string>\n /** Writable paths or envelope patterns, sorted and duplicate-free. */\n readonly writes: ReadonlyArray<string>\n /** `hermetic` or `expected` enforcement. */\n readonly mode: Mode\n /** What a plan does when another node writes an overlapping path. */\n readonly onConflict: ConflictStrategy\n /** The effect tier. Absent means `sealed`. */\n readonly tier?: Tier | undefined\n}\n\n/**\n * Input accepted by {@link make}. Iterables are normalized into sorted,\n * duplicate-free arrays so declarations are deterministic key material.\n * Envelope entries and declared paths must already be path-normalized: no\n * separator or dot-segment rewriting is performed. A declared path containing\n * a whole `.` or `..` segment is never covered and therefore surfaces from\n * {@link narrow} as an `effect_outside_envelope` diagnostic.\n *\n * @category models\n * @since 0.0.0\n */\nexport interface MakeOptions {\n readonly reads: Iterable<string>\n readonly writes: Iterable<string>\n readonly mode: Mode\n readonly onConflict: ConflictStrategy\n readonly tier?: Tier | undefined\n}\n\n/**\n * A result of checking that a step declaration narrows a flow envelope.\n *\n * On failure, `code` names the first rule broken, checked in this order:\n * `effect_outside_envelope` (with the uncovered read and write paths, sorted),\n * `effect_mode_widening`, then `effect_tier_widening` (both with empty\n * `paths`).\n *\n * @category models\n * @since 0.0.0\n */\nexport type NarrowResult =\n | { readonly ok: true }\n | {\n readonly ok: false\n readonly code: \"effect_outside_envelope\" | \"effect_mode_widening\" | \"effect_tier_widening\"\n readonly paths: ReadonlyArray<string>\n }\n\nconst normalize = (paths: Iterable<string>): ReadonlyArray<string> => [...new Set(paths)].sort()\n\n/**\n * Constructs a deterministic effect declaration: `reads` and `writes` are\n * collected, deduplicated, and sorted; an absent `tier` is omitted. Paths are\n * not validated or rewritten.\n *\n * @param input - The paths, mode, conflict strategy, and optional tier.\n * @returns The normalized declaration.\n * @category constructors\n * @since 0.0.0\n */\nexport const make = (input: MakeOptions): Declaration => ({\n reads: normalize(input.reads),\n writes: normalize(input.writes),\n mode: input.mode,\n onConflict: input.onConflict,\n ...(input.tier === undefined ? {} : { tier: input.tier })\n})\n\n/**\n * Checks whether `path` is covered by an envelope entry.\n *\n * The grammar is exhaustive: an exact path matches itself; `*` and `**` match\n * everything; `prefix*` matches by string prefix; and `prefix/**` matches\n * `prefix/` and everything below it, but not bare `prefix`. This is\n * intentionally not full minimatch syntax. Envelope entries and declared paths\n * must be normalized. A path containing a whole `.` or `..` segment is never\n * covered, so {@link narrow} reports it as `effect_outside_envelope` rather\n * than silently accepting an escape.\n *\n * @param envelope - One envelope entry.\n * @param path - One declared path.\n * @returns `true` when the entry covers the path.\n * @category predicates\n * @since 0.0.0\n */\nexport const covers = (envelope: string, path: string): boolean => {\n if (Index.hasDotSegment(path)) return false\n return envelope === path || (Index.isGlob(envelope) && path.startsWith(Index.globPrefix(envelope)))\n}\n\n/**\n * Verifies that a step declaration stays within an enclosing flow envelope.\n *\n * Read and write paths must be covered independently. A step may tighten\n * `expected` to `hermetic`, but cannot widen `hermetic` to `expected`.\n * Effect tiers narrow from irreversible to compensable to sealed.\n *\n * The envelope's lists are prepared once: exact entries go into a set and\n * covering patterns collapse to their outermost prefixes, sorted, so each step\n * path costs one dot-segment scan, one lookup, and one binary search ending in\n * one prefix comparison, whatever the envelope's width or how many of its\n * patterns nest. A graph build prepares each envelope once for every node it\n * encloses.\n *\n * @param envelope - The flow's declaration.\n * @param step - The step's declaration.\n * @returns `{ ok: true }`, or the first rule the step breaks.\n * @category validation\n * @since 0.0.0\n */\nexport const narrow = (envelope: Declaration, step: Declaration): NarrowResult =>\n Index.narrowPrepared(Index.prepareEnvelope(envelope), step)\n\n/**\n * Returns the concrete or narrower write declarations shared by two effect\n * declarations. The result is sorted and duplicate-free.\n *\n * Two declarations of the same literal path always overlap, including a path\n * {@link covers} refuses to match because it carries a `.` or `..` segment.\n * Glob coverage stays strict for those paths, so an unnormalized declaration\n * still escapes no envelope, but two writers naming the same unnormalized path\n * are still detected as writing the same resource.\n *\n * The union of both declarations is indexed once: the distinct paths are\n * sorted, each is scanned once for a dot segment, and each pattern's prefix\n * is located by binary search. Exact paths then match through a merge of two\n * rank lists and each covering pattern enumerates the other declaration's\n * ranks inside its interval, so the cost is linear in the two declarations\n * plus the matches, whatever the paths' lengths or how many patterns nest.\n *\n * @param a - One declaration.\n * @param b - The other declaration.\n * @returns The shared write paths; empty when the writes are disjoint.\n * @category analysis\n * @since 0.0.0\n */\nexport const overlaps = (a: Declaration, b: Declaration): ReadonlyArray<string> => {\n const indexed = Index.indexPaths([a.writes, b.writes])\n return Index.overlapRanks(indexed, Index.rankPaths(indexed, a.writes), Index.rankPaths(indexed, b.writes))\n .map((rank) => indexed.paths[rank]!)\n}\n\n/**\n * Returns a sealed, hermetic copy of an effect declaration, normalized by\n * {@link make}. Paths and `onConflict` are kept.\n *\n * @param declaration - The declaration to copy.\n * @returns The copy with `mode: \"hermetic\"` and `tier: \"sealed\"`.\n * @category constructors\n * @since 0.0.0\n */\nexport const sealed = (declaration: Declaration): Declaration =>\n make({ ...declaration, mode: \"hermetic\", tier: \"sealed\" })\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBA,cAAyB;AACzB,aAAwB;AACxB,YAAuB;AA2GvB,qBASO;AAvGA,MAAM,OAAO,OAAO,SAAS,CAAC,UAAU,eAAe,cAAc,CAAC;AAmBtE,MAAM,OAAO,OAAO,SAAS,CAAC,YAAY,UAAU,CAAC;AAoBrD,MAAM,mBAAmB,OAAO,SAAS,CAAC,aAAa,QAAQ,MAAM,CAAC;AAyBtE,MAAM,WAAW,QAAQ,QAAqB,+BAA+B;AAmGpF,MAAM,YAAY,CAAC,UAAmD,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,EAAE,KAAK;AAYxF,MAAM,OAAO,CAAC,WAAqC;AAAA,EACxD,OAAO,UAAU,MAAM,KAAK;AAAA,EAC5B,QAAQ,UAAU,MAAM,MAAM;AAAA,EAC9B,MAAM,MAAM;AAAA,EACZ,YAAY,MAAM;AAAA,EAClB,GAAI,MAAM,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,KAAK;AACzD;AAmBO,MAAM,SAAS,CAAC,UAAkB,SAA0B;AACjE,MAAI,MAAM,cAAc,IAAI,EAAG,QAAO;AACtC,SAAO,aAAa,QAAS,MAAM,OAAO,QAAQ,KAAK,KAAK,WAAW,MAAM,WAAW,QAAQ,CAAC;AACnG;AAsBO,MAAM,SAAS,CAAC,UAAuB,SAC5C,MAAM,eAAe,MAAM,gBAAgB,QAAQ,GAAG,IAAI;AAyBrD,MAAM,WAAW,CAAC,GAAgB,MAA0C;AACjF,QAAM,UAAU,MAAM,WAAW,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC;AACrD,SAAO,MAAM,aAAa,SAAS,MAAM,UAAU,SAAS,EAAE,MAAM,GAAG,MAAM,UAAU,SAAS,EAAE,MAAM,CAAC,EACtG,IAAI,CAAC,SAAS,QAAQ,MAAM,IAAI,CAAE;AACvC;AAWO,MAAM,SAAS,CAAC,gBACrB,KAAK,EAAE,GAAG,aAAa,MAAM,YAAY,MAAM,SAAS,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/cjs/FileSet.d.ts
CHANGED
|
@@ -43,7 +43,6 @@ export type BoundaryMode = typeof BoundaryMode.Type;
|
|
|
43
43
|
*
|
|
44
44
|
* @category accessors
|
|
45
45
|
* @since 0.1.0
|
|
46
|
-
* @slop
|
|
47
46
|
*/
|
|
48
47
|
export declare const canonical: (path: string) => string;
|
|
49
48
|
/**
|
|
@@ -59,10 +58,15 @@ export declare const canonical: (path: string) => string;
|
|
|
59
58
|
* @since 1.0.0-rc.0
|
|
60
59
|
*/
|
|
61
60
|
export declare const folded: (path: string) => string;
|
|
62
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* A non-empty workspace-relative path or pattern.
|
|
63
|
+
*
|
|
64
|
+
* Decoding fails with a `SchemaError` when {@link workspaceRelative} refuses
|
|
65
|
+
* the string. A bare `Pattern` in a declaration names one literal path; only a
|
|
66
|
+
* {@link Glob} gives `*` and `**` wildcard meaning.
|
|
67
|
+
*
|
|
63
68
|
* @category schemas
|
|
64
69
|
* @since 0.1.0
|
|
65
|
-
* @slop
|
|
66
70
|
*/
|
|
67
71
|
export declare const Pattern: Schema.NonEmptyString;
|
|
68
72
|
/**
|
|
@@ -71,44 +75,59 @@ export declare const Pattern: Schema.NonEmptyString;
|
|
|
71
75
|
* traversal, and the aliasing forms — `.` segments, empty segments — that
|
|
72
76
|
* would let two spellings of one file defeat exact-string overlap detection.
|
|
73
77
|
*
|
|
78
|
+
* C0 controls and DEL are refused as well.
|
|
79
|
+
*
|
|
74
80
|
* @category predicates
|
|
75
81
|
* @since 0.1.0
|
|
76
|
-
* @slop
|
|
77
82
|
*/
|
|
78
83
|
export declare const workspaceRelative: (pattern: string) => boolean;
|
|
79
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* A Bazel-style file glob: the paths matching any `include` pattern and no
|
|
86
|
+
* `exclude` pattern.
|
|
87
|
+
*
|
|
88
|
+
* In a pattern, `*` matches within one path segment and a `**` segment
|
|
89
|
+
* matches zero or more whole segments. A trailing `**` needs its separator,
|
|
90
|
+
* so `src/**` does not match `src` itself.
|
|
91
|
+
*
|
|
80
92
|
* @category schemas
|
|
81
93
|
* @since 0.1.0
|
|
82
|
-
* @slop
|
|
83
94
|
*/
|
|
84
95
|
export declare const Glob: Schema.TaggedStruct<"Glob", {
|
|
85
96
|
readonly include: Schema.NonEmptyArray<Schema.NonEmptyString>;
|
|
86
97
|
readonly exclude: Schema.optional<Schema.$Array<Schema.NonEmptyString>>;
|
|
87
98
|
}>;
|
|
88
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* The value form of {@link Glob}.
|
|
101
|
+
*
|
|
89
102
|
* @category models
|
|
90
103
|
* @since 0.1.0
|
|
91
|
-
* @slop
|
|
92
104
|
*/
|
|
93
105
|
export type Glob = typeof Glob.Type;
|
|
94
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* A directory output captured and replayed as one tree artifact.
|
|
108
|
+
*
|
|
109
|
+
* It covers `path` and every path beneath it, compared in {@link folded}
|
|
110
|
+
* form.
|
|
111
|
+
*
|
|
95
112
|
* @category schemas
|
|
96
113
|
* @since 0.1.0
|
|
97
|
-
* @slop
|
|
98
114
|
*/
|
|
99
115
|
export declare const TreeArtifact: Schema.TaggedStruct<"TreeArtifact", {
|
|
100
116
|
readonly path: Schema.NonEmptyString;
|
|
101
117
|
}>;
|
|
102
|
-
/**
|
|
118
|
+
/**
|
|
119
|
+
* The value form of {@link TreeArtifact}.
|
|
120
|
+
*
|
|
103
121
|
* @category models
|
|
104
122
|
* @since 0.1.0
|
|
105
|
-
* @slop
|
|
106
123
|
*/
|
|
107
124
|
export type TreeArtifact = typeof TreeArtifact.Type;
|
|
108
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* One leaf declaration: a literal path, a {@link Glob}, or a
|
|
127
|
+
* {@link TreeArtifact}. Write sets and filegroups hold entries.
|
|
128
|
+
*
|
|
109
129
|
* @category schemas
|
|
110
130
|
* @since 0.1.0
|
|
111
|
-
* @slop
|
|
112
131
|
*/
|
|
113
132
|
export declare const Entry: Schema.Union<readonly [Schema.NonEmptyString, Schema.TaggedStruct<"Glob", {
|
|
114
133
|
readonly include: Schema.NonEmptyArray<Schema.NonEmptyString>;
|
|
@@ -116,31 +135,40 @@ export declare const Entry: Schema.Union<readonly [Schema.NonEmptyString, Schema
|
|
|
116
135
|
}>, Schema.TaggedStruct<"TreeArtifact", {
|
|
117
136
|
readonly path: Schema.NonEmptyString;
|
|
118
137
|
}>]>;
|
|
119
|
-
/**
|
|
138
|
+
/**
|
|
139
|
+
* The value form of {@link Entry}.
|
|
140
|
+
*
|
|
120
141
|
* @category models
|
|
121
142
|
* @since 0.1.0
|
|
122
|
-
* @slop
|
|
123
143
|
*/
|
|
124
144
|
export type Entry = typeof Entry.Type;
|
|
125
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
* One leaf declaration valid in a read set: a literal path or a {@link Glob}.
|
|
147
|
+
* A read set cannot name a {@link TreeArtifact}, which is an output form.
|
|
148
|
+
*
|
|
126
149
|
* @category schemas
|
|
127
150
|
* @since 0.1.0
|
|
128
|
-
* @slop
|
|
129
151
|
*/
|
|
130
152
|
export declare const ReadEntry: Schema.Union<readonly [Schema.NonEmptyString, Schema.TaggedStruct<"Glob", {
|
|
131
153
|
readonly include: Schema.NonEmptyArray<Schema.NonEmptyString>;
|
|
132
154
|
readonly exclude: Schema.optional<Schema.$Array<Schema.NonEmptyString>>;
|
|
133
155
|
}>]>;
|
|
134
|
-
/**
|
|
156
|
+
/**
|
|
157
|
+
* The value form of {@link ReadEntry}.
|
|
158
|
+
*
|
|
135
159
|
* @category models
|
|
136
160
|
* @since 0.1.0
|
|
137
|
-
* @slop
|
|
138
161
|
*/
|
|
139
162
|
export type ReadEntry = typeof ReadEntry.Type;
|
|
140
|
-
/**
|
|
163
|
+
/**
|
|
164
|
+
* A named, reusable list of {@link Entry} declarations.
|
|
165
|
+
*
|
|
166
|
+
* {@link expand} replaces a filegroup with its entries in place before any
|
|
167
|
+
* overlap check or measurement, so the name never reaches the boundary.
|
|
168
|
+
* Filegroups do not nest.
|
|
169
|
+
*
|
|
141
170
|
* @category schemas
|
|
142
171
|
* @since 0.1.0
|
|
143
|
-
* @slop
|
|
144
172
|
*/
|
|
145
173
|
export declare const Filegroup: Schema.TaggedStruct<"Filegroup", {
|
|
146
174
|
readonly name: Schema.NonEmptyString;
|
|
@@ -151,16 +179,19 @@ export declare const Filegroup: Schema.TaggedStruct<"Filegroup", {
|
|
|
151
179
|
readonly path: Schema.NonEmptyString;
|
|
152
180
|
}>]>>;
|
|
153
181
|
}>;
|
|
154
|
-
/**
|
|
182
|
+
/**
|
|
183
|
+
* The value form of {@link Filegroup}.
|
|
184
|
+
*
|
|
155
185
|
* @category models
|
|
156
186
|
* @since 0.1.0
|
|
157
|
-
* @slop
|
|
158
187
|
*/
|
|
159
188
|
export type Filegroup = typeof Filegroup.Type;
|
|
160
|
-
/**
|
|
189
|
+
/**
|
|
190
|
+
* A {@link Filegroup} restricted to {@link ReadEntry} declarations, for use
|
|
191
|
+
* in a read set. It shares the `"Filegroup"` tag.
|
|
192
|
+
*
|
|
161
193
|
* @category schemas
|
|
162
194
|
* @since 0.1.0
|
|
163
|
-
* @slop
|
|
164
195
|
*/
|
|
165
196
|
export declare const ReadFilegroup: Schema.TaggedStruct<"Filegroup", {
|
|
166
197
|
readonly name: Schema.NonEmptyString;
|
|
@@ -169,16 +200,19 @@ export declare const ReadFilegroup: Schema.TaggedStruct<"Filegroup", {
|
|
|
169
200
|
readonly exclude: Schema.optional<Schema.$Array<Schema.NonEmptyString>>;
|
|
170
201
|
}>]>>;
|
|
171
202
|
}>;
|
|
172
|
-
/**
|
|
203
|
+
/**
|
|
204
|
+
* The value form of {@link ReadFilegroup}.
|
|
205
|
+
*
|
|
173
206
|
* @category models
|
|
174
207
|
* @since 0.1.0
|
|
175
|
-
* @slop
|
|
176
208
|
*/
|
|
177
209
|
export type ReadFilegroup = typeof ReadFilegroup.Type;
|
|
178
|
-
/**
|
|
210
|
+
/**
|
|
211
|
+
* Any declaration accepted in a write set: an {@link Entry} or a
|
|
212
|
+
* {@link Filegroup}.
|
|
213
|
+
*
|
|
179
214
|
* @category schemas
|
|
180
215
|
* @since 0.1.0
|
|
181
|
-
* @slop
|
|
182
216
|
*/
|
|
183
217
|
export declare const Declaration: Schema.Union<readonly [Schema.Union<readonly [Schema.NonEmptyString, Schema.TaggedStruct<"Glob", {
|
|
184
218
|
readonly include: Schema.NonEmptyArray<Schema.NonEmptyString>;
|
|
@@ -194,16 +228,19 @@ export declare const Declaration: Schema.Union<readonly [Schema.Union<readonly [
|
|
|
194
228
|
readonly path: Schema.NonEmptyString;
|
|
195
229
|
}>]>>;
|
|
196
230
|
}>]>;
|
|
197
|
-
/**
|
|
231
|
+
/**
|
|
232
|
+
* The value form of {@link Declaration}.
|
|
233
|
+
*
|
|
198
234
|
* @category models
|
|
199
235
|
* @since 0.1.0
|
|
200
|
-
* @slop
|
|
201
236
|
*/
|
|
202
237
|
export type Declaration = typeof Declaration.Type;
|
|
203
|
-
/**
|
|
238
|
+
/**
|
|
239
|
+
* Any declaration accepted in a read set: a {@link ReadEntry} or a
|
|
240
|
+
* {@link ReadFilegroup}.
|
|
241
|
+
*
|
|
204
242
|
* @category schemas
|
|
205
243
|
* @since 0.1.0
|
|
206
|
-
* @slop
|
|
207
244
|
*/
|
|
208
245
|
export declare const ReadDeclaration: Schema.Union<readonly [Schema.Union<readonly [Schema.NonEmptyString, Schema.TaggedStruct<"Glob", {
|
|
209
246
|
readonly include: Schema.NonEmptyArray<Schema.NonEmptyString>;
|
|
@@ -215,52 +252,86 @@ export declare const ReadDeclaration: Schema.Union<readonly [Schema.Union<readon
|
|
|
215
252
|
readonly exclude: Schema.optional<Schema.$Array<Schema.NonEmptyString>>;
|
|
216
253
|
}>]>>;
|
|
217
254
|
}>]>;
|
|
218
|
-
/**
|
|
255
|
+
/**
|
|
256
|
+
* The value form of {@link ReadDeclaration}.
|
|
257
|
+
*
|
|
219
258
|
* @category models
|
|
220
259
|
* @since 0.1.0
|
|
221
|
-
* @slop
|
|
222
260
|
*/
|
|
223
261
|
export type ReadDeclaration = typeof ReadDeclaration.Type;
|
|
224
|
-
/**
|
|
262
|
+
/**
|
|
263
|
+
* Creates a {@link Filegroup}. It does not validate `name` or `entries`;
|
|
264
|
+
* decode through {@link Filegroup} when the input is untrusted.
|
|
265
|
+
*
|
|
266
|
+
* @param name - The filegroup name.
|
|
267
|
+
* @param entries - The entries the filegroup expands to, in order.
|
|
268
|
+
* @returns The filegroup value.
|
|
225
269
|
* @category constructors
|
|
226
270
|
* @since 0.1.0
|
|
227
|
-
* @slop
|
|
228
271
|
*/
|
|
229
272
|
export declare const makeFilegroup: (name: string, entries: ReadonlyArray<Entry>) => Filegroup;
|
|
230
|
-
/**
|
|
273
|
+
/**
|
|
274
|
+
* Replaces each {@link Filegroup} with its entries, in place, and keeps every
|
|
275
|
+
* other declaration as it is. Order is preserved and duplicates are kept.
|
|
276
|
+
*
|
|
277
|
+
* @param declarations - Write-set declarations, possibly holding filegroups.
|
|
278
|
+
* @returns The flat list of entries.
|
|
231
279
|
* @category accessors
|
|
232
280
|
* @since 0.1.0
|
|
233
|
-
* @slop
|
|
234
281
|
*/
|
|
235
282
|
export declare const expand: (declarations: ReadonlyArray<Declaration>) => ReadonlyArray<Entry>;
|
|
236
|
-
/**
|
|
283
|
+
/**
|
|
284
|
+
* {@link expand} for read sets: replaces each {@link ReadFilegroup} with its
|
|
285
|
+
* entries, in place, preserving order and duplicates.
|
|
286
|
+
*
|
|
287
|
+
* @param declarations - Read-set declarations, possibly holding filegroups.
|
|
288
|
+
* @returns The flat list of read entries.
|
|
237
289
|
* @category accessors
|
|
238
290
|
* @since 0.1.0
|
|
239
|
-
* @slop
|
|
240
291
|
*/
|
|
241
292
|
export declare const expandReads: (declarations: ReadonlyArray<ReadDeclaration>) => ReadonlyArray<ReadEntry>;
|
|
242
|
-
/**
|
|
293
|
+
/**
|
|
294
|
+
* Whether a value carries the `"Glob"` tag. It checks only the tag, not the
|
|
295
|
+
* patterns.
|
|
296
|
+
*
|
|
297
|
+
* @param value - Any value.
|
|
298
|
+
* @returns `true` for an object whose `_tag` is `"Glob"`.
|
|
243
299
|
* @category guards
|
|
244
300
|
* @since 0.1.0
|
|
245
|
-
* @slop
|
|
246
301
|
*/
|
|
247
302
|
export declare const isGlob: (value: unknown) => value is Glob;
|
|
248
|
-
/**
|
|
303
|
+
/**
|
|
304
|
+
* Whether a value carries the `"TreeArtifact"` tag. It checks only the tag,
|
|
305
|
+
* not the path.
|
|
306
|
+
*
|
|
307
|
+
* @param value - Any value.
|
|
308
|
+
* @returns `true` for an object whose `_tag` is `"TreeArtifact"`.
|
|
249
309
|
* @category guards
|
|
250
310
|
* @since 0.1.0
|
|
251
|
-
* @slop
|
|
252
311
|
*/
|
|
253
312
|
export declare const isTreeArtifact: (value: unknown) => value is TreeArtifact;
|
|
254
|
-
/**
|
|
313
|
+
/**
|
|
314
|
+
* Whether `path` matches `pattern` under {@link Glob} wildcard rules.
|
|
315
|
+
*
|
|
316
|
+
* The pattern is read in its {@link canonical} spelling; the path is matched
|
|
317
|
+
* as given, case-sensitively, with `/` as its only separator.
|
|
318
|
+
*
|
|
319
|
+
* @param pattern - A Bazel-style pattern such as `src/*.ts` or `docs/**`.
|
|
320
|
+
* @param path - A workspace-relative path.
|
|
321
|
+
* @returns `true` when the path matches.
|
|
255
322
|
* @category predicates
|
|
256
323
|
* @since 0.1.0
|
|
257
|
-
* @slop
|
|
258
324
|
*/
|
|
259
325
|
export declare const matchesPattern: (pattern: string, path: string) => boolean;
|
|
260
|
-
/**
|
|
326
|
+
/**
|
|
327
|
+
* Whether `path` matches some `include` pattern of `glob` and no `exclude`
|
|
328
|
+
* pattern, each tested with {@link matchesPattern}. Case-sensitive.
|
|
329
|
+
*
|
|
330
|
+
* @param glob - The glob to test.
|
|
331
|
+
* @param path - A workspace-relative path.
|
|
332
|
+
* @returns `true` when the glob selects the path.
|
|
261
333
|
* @category predicates
|
|
262
334
|
* @since 0.1.0
|
|
263
|
-
* @slop
|
|
264
335
|
*/
|
|
265
336
|
export declare const matchesGlob: (glob: Glob, path: string) => boolean;
|
|
266
337
|
/**
|
|
@@ -282,7 +353,6 @@ export declare const matchesGlob: (glob: Glob, path: string) => boolean;
|
|
|
282
353
|
*
|
|
283
354
|
* @category predicates
|
|
284
355
|
* @since 0.1.0
|
|
285
|
-
* @slop
|
|
286
356
|
*/
|
|
287
357
|
export declare const overlaps: (left: Entry, right: Entry) => boolean;
|
|
288
358
|
//# sourceMappingURL=FileSet.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSet.d.ts","sourceRoot":"","sources":["../../src/FileSet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,gDAAwC,CAAA;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAEnD
|
|
1
|
+
{"version":3,"file":"FileSet.d.ts","sourceRoot":"","sources":["../../src/FileSet.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/FileSet.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/FileSet.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Static filesystem declaration vocabulary shared by planning and execution.\n *\n * Declared paths use `/` as their canonical separator and normalize Unicode\n * to NFC. Workspace-relative paths reject C0 controls (U+0000 through U+001F)\n * and DEL (U+007F), which name nothing a supported filesystem can open. C1\n * controls (U+0080 through U+009F) remain accepted because those bytes are\n * legal in a POSIX file name.\n *\n * @since 0.1.0\n */\n\nimport * as Schema from \"effect/Schema\"\n\n/**\n * How strictly a declared file set is enforced at the boundary.\n *\n * `hard` rejects undeclared access. `expected` records access for validation\n * after execution without requiring the sandbox to reject it immediately.\n *\n * This is the ONE spelling of the pair. `Plan.NodeEffects.boundaryMode` is this\n * schema and so is `@smthrs/flow`'s `Action.BoundaryMode`; the literal used to\n * be written out in all three places.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const BoundaryMode = Schema.Literals([\"hard\", \"expected\"])\n\n/**\n * The value form of {@link BoundaryMode}.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type BoundaryMode = typeof BoundaryMode.Type\n\n/**\n * The canonical spelling of a declared path or pattern: every separator is\n * `/`, and Unicode is normalized to NFC.\n *\n * {@link workspaceRelative} accepts a backslash as a separator, so\n * `dist\\same.js` and `dist/same.js` are two spellings of ONE workspace path.\n * Every exact-path comparison in this module goes through this form, because\n * comparing the raw spellings would let the separator alias defeat overlap\n * detection exactly as `.` segments and empty segments would.\n *\n * @category accessors\n * @since 0.1.0\n * @slop\n */\nexport const canonical = (path: string): string => path.replaceAll(\"\\\\\", \"/\").normalize(\"NFC\")\n\n/**\n * The {@link canonical} spelling with letter case folded away.\n *\n * A case-insensitive filesystem (default macOS APFS, Windows NTFS) opens\n * `src/A.ts` and `src/a.ts` as one file, so static overlap compares this form:\n * two declarations that differ only in case must serialize. Folding goes\n * through upper case because that mapping is context-free, so it folds each\n * character alone and commutes with splitting a path into segments.\n *\n * @category accessors\n * @since 1.0.0-rc.0\n */\nexport const folded = (path: string): string => canonical(path).toUpperCase().normalize(\"NFC\")\n\n/** Workspace-relative glob pattern.\n * @category schemas\n * @since 0.1.0\n * @slop\n */\nexport const Pattern = Schema.NonEmptyString.check(\n Schema.makeFilter(\n (pattern) => workspaceRelative(pattern) || \"file patterns must be workspace-relative and cannot traverse upward\",\n { title: \"workspaceRelativePattern\" }\n )\n)\n\n/**\n * Whether a declared path or pattern stays inside the workspace and names it\n * one way only. Refuses absolute paths (POSIX and drive-letter), upward\n * traversal, and the aliasing forms \u2014 `.` segments, empty segments \u2014 that\n * would let two spellings of one file defeat exact-string overlap detection.\n *\n * @category predicates\n * @since 0.1.0\n * @slop\n */\nexport const workspaceRelative = (pattern: string): boolean => {\n for (let index = 0; index < pattern.length; index++) {\n const code = pattern.charCodeAt(index)\n if (code <= 0x1f || code === 0x7f) return false\n }\n if (pattern.startsWith(\"/\")) return false\n const segments = canonical(pattern).split(\"/\")\n // `C:foo` is drive-relative on Windows, so any drive-letter prefix escapes.\n if (/^[A-Za-z]:/.test(segments[0]!) || segments[0]!.endsWith(\":\")) return false\n return segments.every((segment) => segment !== \"..\" && segment !== \".\" && segment !== \"\")\n}\n\n/** Bazel-style file glob.\n * @category schemas\n * @since 0.1.0\n * @slop\n */\nexport const Glob = Schema.TaggedStruct(\"Glob\", {\n include: Schema.NonEmptyArray(Pattern),\n exclude: Schema.optional(Schema.Array(Pattern))\n})\n\n/** Bazel-style file glob.\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport type Glob = typeof Glob.Type\n\n/** A directory output captured and replayed as one tree artifact.\n * @category schemas\n * @since 0.1.0\n * @slop\n */\nexport const TreeArtifact = Schema.TaggedStruct(\"TreeArtifact\", {\n path: Pattern\n})\n\n/** A directory output captured and replayed as one tree artifact.\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport type TreeArtifact = typeof TreeArtifact.Type\n\n/** One leaf of a named filegroup.\n * @category schemas\n * @since 0.1.0\n * @slop\n */\nexport const Entry = Schema.Union([Pattern, Glob, TreeArtifact])\n\n/** One leaf of a named filegroup.\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport type Entry = typeof Entry.Type\n\n/** A declaration valid in a read set.\n * @category schemas\n * @since 0.1.0\n * @slop\n */\nexport const ReadEntry = Schema.Union([Pattern, Glob])\n\n/** A declaration valid in a read set.\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport type ReadEntry = typeof ReadEntry.Type\n\n/** A named reusable collection expanded before measurement.\n * @category schemas\n * @since 0.1.0\n * @slop\n */\nexport const Filegroup = Schema.TaggedStruct(\"Filegroup\", {\n name: Schema.NonEmptyString,\n entries: Schema.Array(Entry)\n})\n\n/** A named reusable collection expanded before measurement.\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport type Filegroup = typeof Filegroup.Type\n\n/** A named read-only collection.\n * @category schemas\n * @since 0.1.0\n * @slop\n */\nexport const ReadFilegroup = Schema.TaggedStruct(\"Filegroup\", {\n name: Schema.NonEmptyString,\n entries: Schema.Array(ReadEntry)\n})\n\n/** A named read-only collection.\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport type ReadFilegroup = typeof ReadFilegroup.Type\n\n/** Any declaration accepted by a plan effect set.\n * @category schemas\n * @since 0.1.0\n * @slop\n */\nexport const Declaration = Schema.Union([Entry, Filegroup])\n\n/** Any declaration accepted by a plan effect set.\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport type Declaration = typeof Declaration.Type\n\n/** Any declaration accepted by a plan read set.\n * @category schemas\n * @since 0.1.0\n * @slop\n */\nexport const ReadDeclaration = Schema.Union([ReadEntry, ReadFilegroup])\n\n/** Any declaration accepted by a plan read set.\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport type ReadDeclaration = typeof ReadDeclaration.Type\n\n/** Creates a named filegroup.\n * @category constructors\n * @since 0.1.0\n * @slop\n */\nexport const makeFilegroup = (name: string, entries: ReadonlyArray<Entry>): Filegroup => ({\n _tag: \"Filegroup\",\n name,\n entries\n})\n\n/** Expands filegroups deterministically, preserving declaration order.\n * @category accessors\n * @since 0.1.0\n * @slop\n */\nexport const expand = (declarations: ReadonlyArray<Declaration>): ReadonlyArray<Entry> =>\n declarations.flatMap((declaration) =>\n typeof declaration !== \"string\" && declaration._tag === \"Filegroup\" ? declaration.entries : [declaration]\n )\n\n/** Expands read filegroups deterministically, preserving declaration order.\n * @category accessors\n * @since 0.1.0\n * @slop\n */\nexport const expandReads = (declarations: ReadonlyArray<ReadDeclaration>): ReadonlyArray<ReadEntry> =>\n declarations.flatMap((declaration) =>\n typeof declaration !== \"string\" && declaration._tag === \"Filegroup\" ? declaration.entries : [declaration]\n )\n\n/** Whether a value is a glob declaration.\n * @category guards\n * @since 0.1.0\n * @slop\n */\nexport const isGlob = (value: unknown): value is Glob =>\n typeof value === \"object\" && value !== null && \"_tag\" in value && value._tag === \"Glob\"\n\n/** Whether a value is a tree artifact declaration.\n * @category guards\n * @since 0.1.0\n * @slop\n */\nexport const isTreeArtifact = (value: unknown): value is TreeArtifact =>\n typeof value === \"object\" && value !== null && \"_tag\" in value && value._tag === \"TreeArtifact\"\n\n/** KMP searches a literal without rescanning a long near-matching prefix. */\nconst literalSearch = (literal: string) => {\n const fallback = new Uint32Array(literal.length)\n let matched = 0\n for (let index = 1; index < literal.length; index++) {\n while (matched > 0 && literal[index] !== literal[matched]) matched = fallback[matched - 1]!\n if (literal[index] === literal[matched]) matched++\n fallback[index] = matched\n }\n return (path: string, start: number, end: number): number => {\n let matched = 0\n for (let index = start; index < end; index++) {\n while (matched > 0 && path[index] !== literal[matched]) matched = fallback[matched - 1]!\n if (path[index] === literal[matched]) matched++\n if (matched === literal.length) return index + 1\n }\n return -1\n }\n}\n\n/** Anchored ends and disjoint literal searches make each segment match linear. */\nconst segmentMatcher = (segment: string): (path: string) => boolean => {\n const chunks = segment.split(/\\*+/)\n const prefix = chunks.shift()!\n if (chunks.length === 0) return (path) => path === prefix\n const suffix = chunks.pop()!\n const searches = chunks.map(literalSearch)\n return (path) => {\n const end = path.length - suffix.length\n if (prefix.length > end || !path.startsWith(prefix) || !path.endsWith(suffix)) return false\n let position = prefix.length\n for (const search of searches) {\n position = search(path, position, end)\n if (position === -1) return false\n }\n return true\n }\n}\n\nconst patternMatchers = new Map<string, (path: string) => boolean>()\n\n/** Compile once per canonical spelling; recursive segments use no backtracking. */\nconst patternMatcher = (pattern: string): (path: string) => boolean => {\n const key = canonical(pattern)\n const cached = patternMatchers.get(key)\n if (cached !== undefined) return cached\n const segments = key.split(\"/\").map((segment) => segment === \"**\" ? undefined : segmentMatcher(segment))\n const matcher = (path: string): boolean => {\n const parts = path.split(\"/\")\n // Suffix membership: next[j] says the remaining pattern matches parts[j..].\n // Each pattern/path segment pair is visited once, even with repeated **.\n let next = new Uint8Array(parts.length + 1)\n next[parts.length] = 1\n for (let index = segments.length - 1; index >= 0; index--) {\n const segment = segments[index]\n const current = new Uint8Array(parts.length + 1)\n for (let part = parts.length - 1; part >= 0; part--) {\n current[part] = segment === undefined\n // A trailing ** accepts every remaining code unit. It still needs\n // the separator preceding it: src/** does not match bare src.\n ? Number(\n index === segments.length - 1 || next[part] === 1 ||\n (parts[part] !== \"\" && current[part + 1] === 1)\n )\n : Number(next[part + 1] === 1 && segment(parts[part]!))\n }\n next = current\n }\n return next[0] === 1\n }\n patternMatchers.set(key, matcher)\n return matcher\n}\n\n/** Tests one workspace-relative path against one Bazel-style pattern.\n * @category predicates\n * @since 0.1.0\n * @slop\n */\nexport const matchesPattern = (pattern: string, path: string): boolean => patternMatcher(pattern)(path)\n\n/** Tests one file path against a glob, including exclusions.\n * @category predicates\n * @since 0.1.0\n * @slop\n */\nexport const matchesGlob = (glob: Glob, path: string): boolean =>\n glob.include.some((pattern) => matchesPattern(pattern, path)) &&\n !(glob.exclude ?? []).some((pattern) => matchesPattern(pattern, path))\n\nconst beneath = (tree: string, path: string): boolean => {\n const root = folded(tree)\n const inside = folded(path)\n return inside === root || inside.startsWith(`${root}/`)\n}\n\n/** {@link matchesGlob} over {@link folded} spellings of the glob and the path. */\nconst matchesGlobFolded = (glob: Glob, path: string): boolean => {\n const inside = folded(path)\n return glob.include.some((pattern) => matchesPattern(folded(pattern), inside)) &&\n !(glob.exclude ?? []).some((pattern) => matchesPattern(folded(pattern), inside))\n}\n\n/**\n * Conservative static overlap. `true` may over-serialize; `false` proves that\n * no path can belong to both declarations.\n *\n * A plain string is a literal path, even when it contains `*` or `**`, as it\n * is at execution (sandbox admission, capture, removal, and replay); wildcard\n * matching belongs to a Glob.\n *\n * Exact paths and tree roots compare in their\n * {@link folded} form, so separator aliases, canonically equivalent Unicode\n * spellings, and spellings that differ only in letter case overlap. A Glob\n * against an exact path matches both its `include` and `exclude` patterns in\n * folded form. {@link matchesGlob} itself stays case-sensitive and tests the path bytes it\n * is handed; its property suite pins a backslash inside a path segment as\n * literal text, so canonicalizing a measured path before matching is its\n * caller's decision, not this module's.\n *\n * @category predicates\n * @since 0.1.0\n * @slop\n */\nexport const overlaps = (left: Entry, right: Entry): boolean => {\n if (typeof left === \"string\" && typeof right === \"string\") return folded(left) === folded(right)\n if (typeof left === \"string\" && isGlob(right)) return matchesGlobFolded(right, left)\n if (isGlob(left) && typeof right === \"string\") return matchesGlobFolded(left, right)\n if (isGlob(left) && isGlob(right)) return true\n if (isTreeArtifact(left) && typeof right === \"string\") return beneath(left.path, right)\n if (typeof left === \"string\" && isTreeArtifact(right)) return beneath(right.path, left)\n if (isTreeArtifact(left) && isTreeArtifact(right)) {\n return beneath(left.path, right.path) || beneath(right.path, left.path)\n }\n if (isTreeArtifact(left) && isGlob(right)) return true\n /* v8 ignore else -- the closed Entry union leaves only Glob/TreeArtifact here */\n if (isGlob(left) && isTreeArtifact(right)) return overlaps(right, left)\n /* v8 ignore next -- Entry's closed union makes every pair return above */\n return true\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,aAAwB;AAejB,MAAM,eAAe,OAAO,SAAS,CAAC,QAAQ,UAAU,CAAC;
|
|
4
|
+
"sourcesContent": ["/**\n * Static filesystem declaration vocabulary shared by planning and execution.\n *\n * Declared paths use `/` as their canonical separator and normalize Unicode\n * to NFC. Workspace-relative paths reject C0 controls (U+0000 through U+001F)\n * and DEL (U+007F), which name nothing a supported filesystem can open. C1\n * controls (U+0080 through U+009F) remain accepted because those bytes are\n * legal in a POSIX file name.\n *\n * @since 0.1.0\n */\n\nimport * as Schema from \"effect/Schema\"\n\n/**\n * How strictly a declared file set is enforced at the boundary.\n *\n * `hard` rejects undeclared access. `expected` records access for validation\n * after execution without requiring the sandbox to reject it immediately.\n *\n * This is the ONE spelling of the pair. `Plan.NodeEffects.boundaryMode` is this\n * schema and so is `@smthrs/flow`'s `Action.BoundaryMode`; the literal used to\n * be written out in all three places.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const BoundaryMode = Schema.Literals([\"hard\", \"expected\"])\n\n/**\n * The value form of {@link BoundaryMode}.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type BoundaryMode = typeof BoundaryMode.Type\n\n/**\n * The canonical spelling of a declared path or pattern: every separator is\n * `/`, and Unicode is normalized to NFC.\n *\n * {@link workspaceRelative} accepts a backslash as a separator, so\n * `dist\\same.js` and `dist/same.js` are two spellings of ONE workspace path.\n * Every exact-path comparison in this module goes through this form, because\n * comparing the raw spellings would let the separator alias defeat overlap\n * detection exactly as `.` segments and empty segments would.\n *\n * @category accessors\n * @since 0.1.0\n */\nexport const canonical = (path: string): string => path.replaceAll(\"\\\\\", \"/\").normalize(\"NFC\")\n\n/**\n * The {@link canonical} spelling with letter case folded away.\n *\n * A case-insensitive filesystem (default macOS APFS, Windows NTFS) opens\n * `src/A.ts` and `src/a.ts` as one file, so static overlap compares this form:\n * two declarations that differ only in case must serialize. Folding goes\n * through upper case because that mapping is context-free, so it folds each\n * character alone and commutes with splitting a path into segments.\n *\n * @category accessors\n * @since 1.0.0-rc.0\n */\nexport const folded = (path: string): string => canonical(path).toUpperCase().normalize(\"NFC\")\n\n/**\n * A non-empty workspace-relative path or pattern.\n *\n * Decoding fails with a `SchemaError` when {@link workspaceRelative} refuses\n * the string. A bare `Pattern` in a declaration names one literal path; only a\n * {@link Glob} gives `*` and `**` wildcard meaning.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Pattern = Schema.NonEmptyString.check(\n Schema.makeFilter(\n (pattern) => workspaceRelative(pattern) || \"file patterns must be workspace-relative and cannot traverse upward\",\n { title: \"workspaceRelativePattern\" }\n )\n)\n\n/**\n * Whether a declared path or pattern stays inside the workspace and names it\n * one way only. Refuses absolute paths (POSIX and drive-letter), upward\n * traversal, and the aliasing forms \u2014 `.` segments, empty segments \u2014 that\n * would let two spellings of one file defeat exact-string overlap detection.\n *\n * C0 controls and DEL are refused as well.\n *\n * @category predicates\n * @since 0.1.0\n */\nexport const workspaceRelative = (pattern: string): boolean => {\n for (let index = 0; index < pattern.length; index++) {\n const code = pattern.charCodeAt(index)\n if (code <= 0x1f || code === 0x7f) return false\n }\n if (pattern.startsWith(\"/\")) return false\n const segments = canonical(pattern).split(\"/\")\n // `C:foo` is drive-relative on Windows, so any drive-letter prefix escapes.\n if (/^[A-Za-z]:/.test(segments[0]!) || segments[0]!.endsWith(\":\")) return false\n return segments.every((segment) => segment !== \"..\" && segment !== \".\" && segment !== \"\")\n}\n\n/**\n * A Bazel-style file glob: the paths matching any `include` pattern and no\n * `exclude` pattern.\n *\n * In a pattern, `*` matches within one path segment and a `**` segment\n * matches zero or more whole segments. A trailing `**` needs its separator,\n * so `src/**` does not match `src` itself.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Glob = Schema.TaggedStruct(\"Glob\", {\n include: Schema.NonEmptyArray(Pattern),\n exclude: Schema.optional(Schema.Array(Pattern))\n})\n\n/**\n * The value form of {@link Glob}.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Glob = typeof Glob.Type\n\n/**\n * A directory output captured and replayed as one tree artifact.\n *\n * It covers `path` and every path beneath it, compared in {@link folded}\n * form.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const TreeArtifact = Schema.TaggedStruct(\"TreeArtifact\", {\n path: Pattern\n})\n\n/**\n * The value form of {@link TreeArtifact}.\n *\n * @category models\n * @since 0.1.0\n */\nexport type TreeArtifact = typeof TreeArtifact.Type\n\n/**\n * One leaf declaration: a literal path, a {@link Glob}, or a\n * {@link TreeArtifact}. Write sets and filegroups hold entries.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Entry = Schema.Union([Pattern, Glob, TreeArtifact])\n\n/**\n * The value form of {@link Entry}.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Entry = typeof Entry.Type\n\n/**\n * One leaf declaration valid in a read set: a literal path or a {@link Glob}.\n * A read set cannot name a {@link TreeArtifact}, which is an output form.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ReadEntry = Schema.Union([Pattern, Glob])\n\n/**\n * The value form of {@link ReadEntry}.\n *\n * @category models\n * @since 0.1.0\n */\nexport type ReadEntry = typeof ReadEntry.Type\n\n/**\n * A named, reusable list of {@link Entry} declarations.\n *\n * {@link expand} replaces a filegroup with its entries in place before any\n * overlap check or measurement, so the name never reaches the boundary.\n * Filegroups do not nest.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Filegroup = Schema.TaggedStruct(\"Filegroup\", {\n name: Schema.NonEmptyString,\n entries: Schema.Array(Entry)\n})\n\n/**\n * The value form of {@link Filegroup}.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Filegroup = typeof Filegroup.Type\n\n/**\n * A {@link Filegroup} restricted to {@link ReadEntry} declarations, for use\n * in a read set. It shares the `\"Filegroup\"` tag.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ReadFilegroup = Schema.TaggedStruct(\"Filegroup\", {\n name: Schema.NonEmptyString,\n entries: Schema.Array(ReadEntry)\n})\n\n/**\n * The value form of {@link ReadFilegroup}.\n *\n * @category models\n * @since 0.1.0\n */\nexport type ReadFilegroup = typeof ReadFilegroup.Type\n\n/**\n * Any declaration accepted in a write set: an {@link Entry} or a\n * {@link Filegroup}.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Declaration = Schema.Union([Entry, Filegroup])\n\n/**\n * The value form of {@link Declaration}.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Declaration = typeof Declaration.Type\n\n/**\n * Any declaration accepted in a read set: a {@link ReadEntry} or a\n * {@link ReadFilegroup}.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ReadDeclaration = Schema.Union([ReadEntry, ReadFilegroup])\n\n/**\n * The value form of {@link ReadDeclaration}.\n *\n * @category models\n * @since 0.1.0\n */\nexport type ReadDeclaration = typeof ReadDeclaration.Type\n\n/**\n * Creates a {@link Filegroup}. It does not validate `name` or `entries`;\n * decode through {@link Filegroup} when the input is untrusted.\n *\n * @param name - The filegroup name.\n * @param entries - The entries the filegroup expands to, in order.\n * @returns The filegroup value.\n * @category constructors\n * @since 0.1.0\n */\nexport const makeFilegroup = (name: string, entries: ReadonlyArray<Entry>): Filegroup => ({\n _tag: \"Filegroup\",\n name,\n entries\n})\n\n/**\n * Replaces each {@link Filegroup} with its entries, in place, and keeps every\n * other declaration as it is. Order is preserved and duplicates are kept.\n *\n * @param declarations - Write-set declarations, possibly holding filegroups.\n * @returns The flat list of entries.\n * @category accessors\n * @since 0.1.0\n */\nexport const expand = (declarations: ReadonlyArray<Declaration>): ReadonlyArray<Entry> =>\n declarations.flatMap((declaration) =>\n typeof declaration !== \"string\" && declaration._tag === \"Filegroup\" ? declaration.entries : [declaration]\n )\n\n/**\n * {@link expand} for read sets: replaces each {@link ReadFilegroup} with its\n * entries, in place, preserving order and duplicates.\n *\n * @param declarations - Read-set declarations, possibly holding filegroups.\n * @returns The flat list of read entries.\n * @category accessors\n * @since 0.1.0\n */\nexport const expandReads = (declarations: ReadonlyArray<ReadDeclaration>): ReadonlyArray<ReadEntry> =>\n declarations.flatMap((declaration) =>\n typeof declaration !== \"string\" && declaration._tag === \"Filegroup\" ? declaration.entries : [declaration]\n )\n\n/**\n * Whether a value carries the `\"Glob\"` tag. It checks only the tag, not the\n * patterns.\n *\n * @param value - Any value.\n * @returns `true` for an object whose `_tag` is `\"Glob\"`.\n * @category guards\n * @since 0.1.0\n */\nexport const isGlob = (value: unknown): value is Glob =>\n typeof value === \"object\" && value !== null && \"_tag\" in value && value._tag === \"Glob\"\n\n/**\n * Whether a value carries the `\"TreeArtifact\"` tag. It checks only the tag,\n * not the path.\n *\n * @param value - Any value.\n * @returns `true` for an object whose `_tag` is `\"TreeArtifact\"`.\n * @category guards\n * @since 0.1.0\n */\nexport const isTreeArtifact = (value: unknown): value is TreeArtifact =>\n typeof value === \"object\" && value !== null && \"_tag\" in value && value._tag === \"TreeArtifact\"\n\n/** KMP searches a literal without rescanning a long near-matching prefix. */\nconst literalSearch = (literal: string) => {\n const fallback = new Uint32Array(literal.length)\n let matched = 0\n for (let index = 1; index < literal.length; index++) {\n while (matched > 0 && literal[index] !== literal[matched]) matched = fallback[matched - 1]!\n if (literal[index] === literal[matched]) matched++\n fallback[index] = matched\n }\n return (path: string, start: number, end: number): number => {\n let matched = 0\n for (let index = start; index < end; index++) {\n while (matched > 0 && path[index] !== literal[matched]) matched = fallback[matched - 1]!\n if (path[index] === literal[matched]) matched++\n if (matched === literal.length) return index + 1\n }\n return -1\n }\n}\n\n/** Anchored ends and disjoint literal searches make each segment match linear. */\nconst segmentMatcher = (segment: string): (path: string) => boolean => {\n const chunks = segment.split(/\\*+/)\n const prefix = chunks.shift()!\n if (chunks.length === 0) return (path) => path === prefix\n const suffix = chunks.pop()!\n const searches = chunks.map(literalSearch)\n return (path) => {\n const end = path.length - suffix.length\n if (prefix.length > end || !path.startsWith(prefix) || !path.endsWith(suffix)) return false\n let position = prefix.length\n for (const search of searches) {\n position = search(path, position, end)\n if (position === -1) return false\n }\n return true\n }\n}\n\nconst patternMatchers = new Map<string, (path: string) => boolean>()\n\n/** Compile once per canonical spelling; recursive segments use no backtracking. */\nconst patternMatcher = (pattern: string): (path: string) => boolean => {\n const key = canonical(pattern)\n const cached = patternMatchers.get(key)\n if (cached !== undefined) return cached\n const segments = key.split(\"/\").map((segment) => segment === \"**\" ? undefined : segmentMatcher(segment))\n const matcher = (path: string): boolean => {\n const parts = path.split(\"/\")\n // Suffix membership: next[j] says the remaining pattern matches parts[j..].\n // Each pattern/path segment pair is visited once, even with repeated **.\n let next = new Uint8Array(parts.length + 1)\n next[parts.length] = 1\n for (let index = segments.length - 1; index >= 0; index--) {\n const segment = segments[index]\n const current = new Uint8Array(parts.length + 1)\n for (let part = parts.length - 1; part >= 0; part--) {\n current[part] = segment === undefined\n // A trailing ** accepts every remaining code unit. It still needs\n // the separator preceding it: src/** does not match bare src.\n ? Number(\n index === segments.length - 1 || next[part] === 1 ||\n (parts[part] !== \"\" && current[part + 1] === 1)\n )\n : Number(next[part + 1] === 1 && segment(parts[part]!))\n }\n next = current\n }\n return next[0] === 1\n }\n patternMatchers.set(key, matcher)\n return matcher\n}\n\n/**\n * Whether `path` matches `pattern` under {@link Glob} wildcard rules.\n *\n * The pattern is read in its {@link canonical} spelling; the path is matched\n * as given, case-sensitively, with `/` as its only separator.\n *\n * @param pattern - A Bazel-style pattern such as `src/*.ts` or `docs/**`.\n * @param path - A workspace-relative path.\n * @returns `true` when the path matches.\n * @category predicates\n * @since 0.1.0\n */\nexport const matchesPattern = (pattern: string, path: string): boolean => patternMatcher(pattern)(path)\n\n/**\n * Whether `path` matches some `include` pattern of `glob` and no `exclude`\n * pattern, each tested with {@link matchesPattern}. Case-sensitive.\n *\n * @param glob - The glob to test.\n * @param path - A workspace-relative path.\n * @returns `true` when the glob selects the path.\n * @category predicates\n * @since 0.1.0\n */\nexport const matchesGlob = (glob: Glob, path: string): boolean =>\n glob.include.some((pattern) => matchesPattern(pattern, path)) &&\n !(glob.exclude ?? []).some((pattern) => matchesPattern(pattern, path))\n\nconst beneath = (tree: string, path: string): boolean => {\n const root = folded(tree)\n const inside = folded(path)\n return inside === root || inside.startsWith(`${root}/`)\n}\n\n/** {@link matchesGlob} over {@link folded} spellings of the glob and the path. */\nconst matchesGlobFolded = (glob: Glob, path: string): boolean => {\n const inside = folded(path)\n return glob.include.some((pattern) => matchesPattern(folded(pattern), inside)) &&\n !(glob.exclude ?? []).some((pattern) => matchesPattern(folded(pattern), inside))\n}\n\n/**\n * Conservative static overlap. `true` may over-serialize; `false` proves that\n * no path can belong to both declarations.\n *\n * A plain string is a literal path, even when it contains `*` or `**`, as it\n * is at execution (sandbox admission, capture, removal, and replay); wildcard\n * matching belongs to a Glob.\n *\n * Exact paths and tree roots compare in their\n * {@link folded} form, so separator aliases, canonically equivalent Unicode\n * spellings, and spellings that differ only in letter case overlap. A Glob\n * against an exact path matches both its `include` and `exclude` patterns in\n * folded form. {@link matchesGlob} itself stays case-sensitive and tests the path bytes it\n * is handed; its property suite pins a backslash inside a path segment as\n * literal text, so canonicalizing a measured path before matching is its\n * caller's decision, not this module's.\n *\n * @category predicates\n * @since 0.1.0\n */\nexport const overlaps = (left: Entry, right: Entry): boolean => {\n if (typeof left === \"string\" && typeof right === \"string\") return folded(left) === folded(right)\n if (typeof left === \"string\" && isGlob(right)) return matchesGlobFolded(right, left)\n if (isGlob(left) && typeof right === \"string\") return matchesGlobFolded(left, right)\n if (isGlob(left) && isGlob(right)) return true\n if (isTreeArtifact(left) && typeof right === \"string\") return beneath(left.path, right)\n if (typeof left === \"string\" && isTreeArtifact(right)) return beneath(right.path, left)\n if (isTreeArtifact(left) && isTreeArtifact(right)) {\n return beneath(left.path, right.path) || beneath(right.path, left.path)\n }\n if (isTreeArtifact(left) && isGlob(right)) return true\n /* v8 ignore else -- the closed Entry union leaves only Glob/TreeArtifact here */\n if (isGlob(left) && isTreeArtifact(right)) return overlaps(right, left)\n /* v8 ignore next -- Entry's closed union makes every pair return above */\n return true\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["matched"]
|
|
7
7
|
}
|