@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.
Files changed (59) hide show
  1. package/dist/cjs/Effects.d.ts +29 -11
  2. package/dist/cjs/Effects.d.ts.map +1 -1
  3. package/dist/cjs/Effects.js.map +2 -2
  4. package/dist/cjs/FileSet.d.ts +121 -51
  5. package/dist/cjs/FileSet.d.ts.map +1 -1
  6. package/dist/cjs/FileSet.js.map +2 -2
  7. package/dist/cjs/GraphBuildError.d.ts +2 -4
  8. package/dist/cjs/GraphBuildError.d.ts.map +1 -1
  9. package/dist/cjs/GraphBuildError.js.map +2 -2
  10. package/dist/cjs/KeyMaterial.d.ts +13 -8
  11. package/dist/cjs/KeyMaterial.d.ts.map +1 -1
  12. package/dist/cjs/KeyMaterial.js.map +2 -2
  13. package/dist/cjs/Plan.d.ts +72 -23
  14. package/dist/cjs/Plan.d.ts.map +1 -1
  15. package/dist/cjs/Plan.js +3 -0
  16. package/dist/cjs/Plan.js.map +2 -2
  17. package/dist/cjs/PlanDiff.d.ts +7 -3
  18. package/dist/cjs/PlanDiff.d.ts.map +1 -1
  19. package/dist/cjs/PlanDiff.js.map +2 -2
  20. package/dist/cjs/StepKey.d.ts +38 -17
  21. package/dist/cjs/StepKey.d.ts.map +1 -1
  22. package/dist/cjs/StepKey.js.map +2 -2
  23. package/dist/esm/Effects.d.ts +29 -11
  24. package/dist/esm/Effects.d.ts.map +1 -1
  25. package/dist/esm/Effects.js +18 -7
  26. package/dist/esm/Effects.js.map +1 -1
  27. package/dist/esm/FileSet.d.ts +121 -51
  28. package/dist/esm/FileSet.d.ts.map +1 -1
  29. package/dist/esm/FileSet.js +97 -35
  30. package/dist/esm/FileSet.js.map +1 -1
  31. package/dist/esm/GraphBuildError.d.ts +2 -4
  32. package/dist/esm/GraphBuildError.d.ts.map +1 -1
  33. package/dist/esm/GraphBuildError.js +2 -3
  34. package/dist/esm/GraphBuildError.js.map +1 -1
  35. package/dist/esm/KeyMaterial.d.ts +13 -8
  36. package/dist/esm/KeyMaterial.d.ts.map +1 -1
  37. package/dist/esm/KeyMaterial.js +11 -4
  38. package/dist/esm/KeyMaterial.js.map +1 -1
  39. package/dist/esm/Plan.d.ts +72 -23
  40. package/dist/esm/Plan.d.ts.map +1 -1
  41. package/dist/esm/Plan.js +61 -16
  42. package/dist/esm/Plan.js.map +1 -1
  43. package/dist/esm/PlanDiff.d.ts +7 -3
  44. package/dist/esm/PlanDiff.d.ts.map +1 -1
  45. package/dist/esm/PlanDiff.js +0 -1
  46. package/dist/esm/PlanDiff.js.map +1 -1
  47. package/dist/esm/StepKey.d.ts +38 -17
  48. package/dist/esm/StepKey.d.ts.map +1 -1
  49. package/dist/esm/StepKey.js +33 -11
  50. package/dist/esm/StepKey.js.map +1 -1
  51. package/docs/guides/diff-two-plans.md +78 -1
  52. package/package.json +4 -4
  53. package/src/Effects.ts +29 -11
  54. package/src/FileSet.ts +121 -51
  55. package/src/GraphBuildError.ts +2 -4
  56. package/src/KeyMaterial.ts +13 -8
  57. package/src/Plan.ts +66 -23
  58. package/src/PlanDiff.ts +7 -3
  59. package/src/StepKey.ts +38 -17
@@ -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;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACrC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACtC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAA;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;CACjC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACjC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAA;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;CACjC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GACrB;IACA,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAA;IAClB,QAAQ,CAAC,IAAI,EAAE,yBAAyB,GAAG,sBAAsB,GAAG,sBAAsB,CAAA;IAC1F,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACtC,CAAA;AAIH;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,GAAI,OAAO,WAAW,KAAG,WAMxC,CAAA;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,MAAM,GAAI,UAAU,MAAM,EAAE,MAAM,MAAM,KAAG,OAGvD,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,MAAM,GAAI,UAAU,WAAW,EAAE,MAAM,WAAW,KAAG,YACL,CAAA;AAE7D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,QAAQ,GAAI,GAAG,WAAW,EAAE,GAAG,WAAW,KAAG,aAAa,CAAC,MAAM,CAI7E,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,GAAI,aAAa,WAAW,KAAG,WACU,CAAA"}
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;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACrC,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACtC,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAA;IACrC,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;CACjC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACjC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAA;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;CACjC;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GACrB;IACA,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAA;IAClB,QAAQ,CAAC,IAAI,EAAE,yBAAyB,GAAG,sBAAsB,GAAG,sBAAsB,CAAA;IAC1F,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACtC,CAAA;AAIH;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI,GAAI,OAAO,WAAW,KAAG,WAMxC,CAAA;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,MAAM,GAAI,UAAU,MAAM,EAAE,MAAM,MAAM,KAAG,OAGvD,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,MAAM,GAAI,UAAU,WAAW,EAAE,MAAM,WAAW,KAAG,YACL,CAAA;AAE7D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,QAAQ,GAAI,GAAG,WAAW,EAAE,GAAG,WAAW,KAAG,aAAa,CAAC,MAAM,CAI7E,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,GAAI,aAAa,WAAW,KAAG,WACU,CAAA"}
@@ -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;AA4FpF,MAAM,YAAY,CAAC,UAAmD,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,EAAE,KAAK;AASxF,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;AAiBO,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;AAoBO,MAAM,SAAS,CAAC,UAAuB,SAC5C,MAAM,eAAe,MAAM,gBAAgB,QAAQ,GAAG,IAAI;AAuBrD,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;AASO,MAAM,SAAS,CAAC,gBACrB,KAAK,EAAE,GAAG,aAAa,MAAM,YAAY,MAAM,SAAS,CAAC;",
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
  }
@@ -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
- /** Workspace-relative glob pattern.
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
- /** Bazel-style file glob.
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
- /** Bazel-style file glob.
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
- /** A directory output captured and replayed as one tree artifact.
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
- /** A directory output captured and replayed as one tree artifact.
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
- /** One leaf of a named filegroup.
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
- /** One leaf of a named filegroup.
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
- /** A declaration valid in a read set.
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
- /** A declaration valid in a read set.
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
- /** A named reusable collection expanded before measurement.
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
- /** A named reusable collection expanded before measurement.
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
- /** A named read-only collection.
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
- /** A named read-only collection.
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
- /** Any declaration accepted by a plan effect set.
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
- /** Any declaration accepted by a plan effect set.
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
- /** Any declaration accepted by a plan read set.
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
- /** Any declaration accepted by a plan read set.
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
- /** Creates a named filegroup.
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
- /** Expands filegroups deterministically, preserving declaration order.
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
- /** Expands read filegroups deterministically, preserving declaration order.
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
- /** Whether a value is a glob declaration.
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
- /** Whether a value is a tree artifact declaration.
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
- /** Tests one workspace-relative path against one Bazel-style pattern.
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
- /** Tests one file path against a glob, including exclusions.
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":"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"}
1
+ {"version":3,"file":"FileSet.d.ts","sourceRoot":"","sources":["../../src/FileSet.ts"],"names":[],"mappings":"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"}
@@ -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": "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",
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
  }