@systemfsoftware/trace-spec 0.5.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +1 -1
- package/dist/index.d.ts +11 -9
- package/dist/index.mjs +486 -212
- package/package.json +22 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @systemfsoftware/trace-spec
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Require `effect` `^4` (stable 4.0.0). Release candidates are no longer supported: imports follow 4.0.0's module layout (`effect/http`, `effect/rpc`, `effect/http-api`, `effect/cluster`, `effect/process`, `effect/socket`, `effect/persistence`, `effect/reactivity`, `effect/encoding`, `effect/Arbitrary`), which does not exist in any 4.0.0 RC.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies:
|
|
12
|
+
- @systemfsoftware/effect-cell-types@12.0.0
|
|
13
|
+
- @systemfsoftware/effect-spec-runtime@1.0.0
|
|
14
|
+
- @systemfsoftware/trace-taxonomy@1.0.0
|
|
15
|
+
- @systemfsoftware/vitest@1.0.0
|
|
16
|
+
|
|
17
|
+
## 0.5.2
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies:
|
|
22
|
+
- @systemfsoftware/vitest@0.3.0
|
|
23
|
+
|
|
3
24
|
## 0.5.1
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -96,7 +96,7 @@ When the behaviour runs in another process — a CLI binary, a worker, a contain
|
|
|
96
96
|
```ts
|
|
97
97
|
import { RemoteObservation, TempoTraceStore } from '@systemfsoftware/trace-spec'
|
|
98
98
|
import { Layer } from 'effect'
|
|
99
|
-
import { FetchHttpClient } from 'effect/
|
|
99
|
+
import { FetchHttpClient } from 'effect/http'
|
|
100
100
|
|
|
101
101
|
const observation = RemoteObservation.layer(
|
|
102
102
|
TempoTraceStore.source({ baseUrl: 'http://127.0.0.1:3200' }),
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { Context, Duration, Effect, FileSystem, Layer,
|
|
1
|
+
import { Context, Duration, Effect, FileSystem, Layer, Option, Schema } from "effect";
|
|
2
2
|
import { Pipeable } from "effect/Pipeable";
|
|
3
3
|
import { Span, Taxonomy } from "@systemfsoftware/trace-taxonomy";
|
|
4
|
-
import * as
|
|
5
|
-
import * as
|
|
4
|
+
import * as Result$1 from "effect/Result";
|
|
5
|
+
import * as HttpClient from "effect/http/HttpClient";
|
|
6
6
|
import { Blueprint, Handle } from "@systemfsoftware/effect-cell-types";
|
|
7
|
+
import * as OtelTracer from "@effect/opentelemetry/OtelTracer";
|
|
7
8
|
import { BasicTracerProvider, ReadableSpan } from "@opentelemetry/sdk-trace-base";
|
|
8
9
|
import { Suite } from "@systemfsoftware/effect-spec-runtime";
|
|
9
10
|
import { Asserted, Check, Expect } from "@systemfsoftware/vitest";
|
|
10
11
|
import * as Scope from "effect/Scope";
|
|
11
|
-
import * as Arbitrary from "effect/
|
|
12
|
+
import * as Arbitrary from "effect/Arbitrary";
|
|
12
13
|
//#region src/BreakFailure.schema.d.ts
|
|
13
14
|
declare const BreakFailure_base: Schema.Class<BreakFailure, Schema.TaggedStruct<"BreakFailure", {
|
|
14
15
|
readonly report: Schema.String;
|
|
@@ -126,9 +127,7 @@ declare const TraceGraph: Schema.Struct<{
|
|
|
126
127
|
}>>;
|
|
127
128
|
}>;
|
|
128
129
|
type TraceGraph = typeof TraceGraph.Type;
|
|
129
|
-
|
|
130
|
-
export { AttributeValue, Attributes, GraphNode, SpanEvent, SpanLink, SpanRecord, Status, TraceGraph, byId, children, decode, descendants };
|
|
131
|
-
}
|
|
130
|
+
type GraphDecoded = Result$1.Result<TraceGraph, ContractDecodeError>;
|
|
132
131
|
declare const byId: {
|
|
133
132
|
(spec: Span.Span): (graph: TraceGraph) => ReadonlyArray<GraphNode>;
|
|
134
133
|
(graph: TraceGraph, spec: Span.Span): ReadonlyArray<GraphNode>;
|
|
@@ -149,9 +148,12 @@ declare const descendants: {
|
|
|
149
148
|
* fail the pipeline by accident.
|
|
150
149
|
*/
|
|
151
150
|
declare const decode: {
|
|
152
|
-
(spans: ReadonlyArray<SpanRecord>, taxonomy: Taxonomy.Taxonomy): (traceId: string) =>
|
|
153
|
-
(traceId: string, spans: ReadonlyArray<SpanRecord>, taxonomy: Taxonomy.Taxonomy):
|
|
151
|
+
(spans: ReadonlyArray<SpanRecord>, taxonomy: Taxonomy.Taxonomy): (traceId: string) => GraphDecoded;
|
|
152
|
+
(traceId: string, spans: ReadonlyArray<SpanRecord>, taxonomy: Taxonomy.Taxonomy): GraphDecoded;
|
|
154
153
|
};
|
|
154
|
+
declare namespace Graph_d_exports {
|
|
155
|
+
export { AttributeValue, Attributes, GraphDecoded, GraphNode, SpanEvent, SpanLink, SpanRecord, Status, TraceGraph, byId, children, decode, descendants };
|
|
156
|
+
}
|
|
155
157
|
//#endregion
|
|
156
158
|
//#region src/TransportObservationError.schema.d.ts
|
|
157
159
|
declare const TransportObservationError_base: Schema.Class<TransportObservationError, Schema.TaggedStruct<"TransportObservationError", {
|
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { callFrameOutside, withRaisingFrame } from "@systemfsoftware/vitest/failure";
|
|
3
|
-
import { Array as Array$1, Cause, Clock, Context, Duration, Effect,
|
|
4
|
-
import { dual } from "effect/Function";
|
|
3
|
+
import { Array as Array$1, Cause, Clock, Context, Duration, Effect, Equal, FileSystem, Layer, Match, Option, Predicate, Random, Ref, Result, Schema, SchemaGetter, SchemaTransformation } from "effect";
|
|
4
|
+
import { absurd, dual } from "effect/Function";
|
|
5
5
|
import { Prototype } from "effect/Pipeable";
|
|
6
6
|
import "effect/PlatformError";
|
|
7
7
|
import "@systemfsoftware/trace-taxonomy";
|
|
8
8
|
import "effect/Array";
|
|
9
|
-
import "effect/Result";
|
|
10
|
-
import * as HttpClient from "effect/
|
|
11
|
-
import * as HttpClientRequest from "effect/
|
|
12
|
-
import * as HttpClientResponse from "effect/
|
|
9
|
+
import * as Result$1 from "effect/Result";
|
|
10
|
+
import * as HttpClient from "effect/http/HttpClient";
|
|
11
|
+
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
12
|
+
import * as HttpClientResponse from "effect/http/HttpClientResponse";
|
|
13
|
+
import { Blueprint, Handle, Workflow } from "@systemfsoftware/effect-cell-types";
|
|
14
|
+
import { Hex } from "effect/encoding";
|
|
13
15
|
import * as OtelTracer from "@effect/opentelemetry/OtelTracer";
|
|
14
16
|
import * as OtelResource from "@effect/opentelemetry/Resource";
|
|
15
|
-
import { Blueprint, Handle } from "@systemfsoftware/effect-cell-types";
|
|
16
17
|
import { SpanStatusCode } from "@opentelemetry/api";
|
|
17
18
|
import { AlwaysOnSampler, BasicTracerProvider } from "@opentelemetry/sdk-trace-base";
|
|
18
19
|
import { Suite, TaskRef } from "@systemfsoftware/effect-spec-runtime";
|
|
@@ -46,64 +47,6 @@ var EmptyObservationError = class extends Schema.TaggedError()("EmptyObservation
|
|
|
46
47
|
}
|
|
47
48
|
};
|
|
48
49
|
//#endregion
|
|
49
|
-
//#region src/Verdict.schema.ts
|
|
50
|
-
const Hold = Schema.TaggedStruct("Hold", {
|
|
51
|
-
conjunct: Schema.String,
|
|
52
|
-
inspected: Schema.Array(Schema.String)
|
|
53
|
-
});
|
|
54
|
-
const Break = Schema.TaggedStruct("Break", {
|
|
55
|
-
conjunct: Schema.String,
|
|
56
|
-
inspected: Schema.Array(Schema.String),
|
|
57
|
-
detail: Schema.String
|
|
58
|
-
});
|
|
59
|
-
const Verdict = Schema.Union([Hold, Break]);
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region src/FailureDump.ts
|
|
62
|
-
const DEFAULT_DIRECTORY = "artifacts/traces";
|
|
63
|
-
const isBreak$1 = Schema.is(Break);
|
|
64
|
-
/**
|
|
65
|
-
* The rendered evidence a break carries; a held verdict leaves nothing to write.
|
|
66
|
-
*/
|
|
67
|
-
const report = (verdict) => Option.map(Option.liftPredicate(verdict, isBreak$1), renderBreach);
|
|
68
|
-
const renderValue = (value) => JSON.stringify(value);
|
|
69
|
-
const renderEntries = (entries) => [...entries].map(([key, value]) => `${key}=${renderValue(value)}`).join(" ");
|
|
70
|
-
const indentOf = (depth) => " ".repeat(depth);
|
|
71
|
-
const renderBreach = (breach) => `break ${breach.conjunct} inspected=[${breach.inspected.join(", ")}]\n${indentOf(1)}${breach.detail}`;
|
|
72
|
-
const childrenOf = (spans, spanId) => spans.filter((span) => span.parentSpanId === spanId);
|
|
73
|
-
const renderNode = (spans, node, depth) => {
|
|
74
|
-
return [`${indentOf(depth)}${node.name} (${node.spanId}) status=${node.status} error.type=${String(node.errorType)} duration=${node.durationMillis}ms`, ...[
|
|
75
|
-
`${indentOf(depth)} attrs: ${renderEntries(Object.entries(node.attributes))}`,
|
|
76
|
-
...node.events.map((event) => `${indentOf(depth)} event ${event.name} ${renderEntries(Object.entries(event.attributes))}`),
|
|
77
|
-
...node.links.map((link) => `${indentOf(depth)} link ${link.traceId}/${link.spanId}`),
|
|
78
|
-
...childrenOf(spans, node.spanId).map((child) => renderNode(spans, child, depth + 1))
|
|
79
|
-
]].join("\n");
|
|
80
|
-
};
|
|
81
|
-
const documentImpl = (observed, report) => [
|
|
82
|
-
`trace ${observed.traceId}`,
|
|
83
|
-
report,
|
|
84
|
-
...observed.spans.map((node) => renderNode(observed.spans, node, 0))
|
|
85
|
-
].join("\n");
|
|
86
|
-
/**
|
|
87
|
-
* The dump document: the trace it belongs to, the break that refused it, and the recorded
|
|
88
|
-
* spans as the observation window saw them.
|
|
89
|
-
*/
|
|
90
|
-
const document = dual(2, documentImpl);
|
|
91
|
-
const sanitize = (value) => value.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
92
|
-
const fileNameOf = (request) => `${sanitize(request.name ?? request.traceId)}.${sanitize(request.conjunct)}.txt`;
|
|
93
|
-
/**
|
|
94
|
-
* Writes the dump under the artifacts directory and answers with its path. The file is
|
|
95
|
-
* named after the request's name when one is given — a generated case names its dump after
|
|
96
|
-
* itself, so every failing draw overwrites one file and the last write is the reported
|
|
97
|
-
* counterexample.
|
|
98
|
-
*/
|
|
99
|
-
const write = (request) => Effect.gen(function* () {
|
|
100
|
-
const fs = yield* FileSystem.FileSystem;
|
|
101
|
-
yield* fs.makeDirectory(DEFAULT_DIRECTORY, { recursive: true });
|
|
102
|
-
const path = `${DEFAULT_DIRECTORY}/${fileNameOf(request)}`;
|
|
103
|
-
yield* fs.writeFileString(path, document(request, request.report));
|
|
104
|
-
return path;
|
|
105
|
-
});
|
|
106
|
-
//#endregion
|
|
107
50
|
//#region src/TraceGraph.schema.ts
|
|
108
51
|
const Status = Schema.Literals([
|
|
109
52
|
"ok",
|
|
@@ -159,22 +102,6 @@ const TraceGraph = Schema.Struct({
|
|
|
159
102
|
traceId: Schema.String,
|
|
160
103
|
nodes: Schema.Array(GraphNode)
|
|
161
104
|
});
|
|
162
|
-
//#endregion
|
|
163
|
-
//#region src/Graph.ts
|
|
164
|
-
var Graph_exports = /* @__PURE__ */ __exportAll({
|
|
165
|
-
AttributeValue: () => AttributeValue,
|
|
166
|
-
Attributes: () => Attributes,
|
|
167
|
-
GraphNode: () => GraphNode,
|
|
168
|
-
SpanEvent: () => SpanEvent,
|
|
169
|
-
SpanLink: () => SpanLink,
|
|
170
|
-
SpanRecord: () => SpanRecord,
|
|
171
|
-
Status: () => Status,
|
|
172
|
-
TraceGraph: () => TraceGraph,
|
|
173
|
-
byId: () => byId,
|
|
174
|
-
children: () => children,
|
|
175
|
-
decode: () => decode,
|
|
176
|
-
descendants: () => descendants
|
|
177
|
-
});
|
|
178
105
|
const byIdImpl = (graph, spec) => graph.nodes.filter((node) => node.name === spec.name);
|
|
179
106
|
const byId = dual(2, byIdImpl);
|
|
180
107
|
const childrenImpl = (graph, node) => graph.nodes.filter((candidate) => candidate.parentSpanId === node.spanId);
|
|
@@ -204,7 +131,7 @@ const decodeFailure = (spec, record, detail, attribute) => ContractDecodeError.m
|
|
|
204
131
|
attribute: attribute ?? "*",
|
|
205
132
|
detail
|
|
206
133
|
});
|
|
207
|
-
const decodeAttrs = (spec, record) => Result.mapError(Schema.decodeResult(Schema.toType(spec.attrs))(record.attributes), (error) => decodeFailure(spec, record, error.message, attributeNameOf(error.issue)));
|
|
134
|
+
const decodeAttrs = (spec, record) => Result$1.mapError(Schema.decodeResult(Schema.toType(spec.attrs))(record.attributes), (error) => decodeFailure(spec, record, error.message, attributeNameOf(error.issue)));
|
|
208
135
|
const nodeOf = (record, attrs) => ({
|
|
209
136
|
spanId: record.spanId,
|
|
210
137
|
parentSpanId: record.parentSpanId,
|
|
@@ -217,10 +144,10 @@ const nodeOf = (record, attrs) => ({
|
|
|
217
144
|
events: record.events,
|
|
218
145
|
links: record.links
|
|
219
146
|
});
|
|
220
|
-
const decodedNodeOf = (record, spec) => Result.map(decodeAttrs(spec, record), (attrs) => nodeOf(record, attrs));
|
|
147
|
+
const decodedNodeOf = (record, spec) => Result$1.map(decodeAttrs(spec, record), (attrs) => nodeOf(record, attrs));
|
|
221
148
|
const declaredNodeOf = (record, declarations) => {
|
|
222
149
|
const spec = declarations.get(record.name);
|
|
223
|
-
return spec === void 0 ? Result.succeed(nodeOf(record, record.attributes)) : decodedNodeOf(record, spec);
|
|
150
|
+
return spec === void 0 ? Result$1.succeed(nodeOf(record, record.attributes)) : decodedNodeOf(record, spec);
|
|
224
151
|
};
|
|
225
152
|
const graphOf = (traceId, nodes) => ({
|
|
226
153
|
traceId,
|
|
@@ -228,7 +155,7 @@ const graphOf = (traceId, nodes) => ({
|
|
|
228
155
|
});
|
|
229
156
|
const decodeImpl = (traceId, spans, taxonomy) => {
|
|
230
157
|
const declarations = indexDeclarations(taxonomy);
|
|
231
|
-
return Result.map(Result.all(spans.map((record) => declaredNodeOf(record, declarations))), (nodes) => graphOf(traceId, nodes));
|
|
158
|
+
return Result$1.map(Result$1.all(spans.map((record) => declaredNodeOf(record, declarations))), (nodes) => graphOf(traceId, nodes));
|
|
232
159
|
};
|
|
233
160
|
/**
|
|
234
161
|
* Decodes the recorded spans of one trace against a taxonomy, purely: a declared span
|
|
@@ -238,6 +165,56 @@ const decodeImpl = (traceId, spans, taxonomy) => {
|
|
|
238
165
|
* fail the pipeline by accident.
|
|
239
166
|
*/
|
|
240
167
|
const decode = dual(3, decodeImpl);
|
|
168
|
+
Schema.Struct({
|
|
169
|
+
traceId: Schema.String,
|
|
170
|
+
spans: Schema.Array(SpanRecord)
|
|
171
|
+
});
|
|
172
|
+
const renderValue = (value) => JSON.stringify(value);
|
|
173
|
+
const renderEntries = (entries) => [...entries].map(([key, value]) => `${key}=${renderValue(value)}`).join(" ");
|
|
174
|
+
const indentOf$1 = (depth) => " ".repeat(depth);
|
|
175
|
+
const childrenOf = (spans, spanId) => spans.filter((span) => span.parentSpanId === spanId);
|
|
176
|
+
const renderNode = (spans, node, depth) => {
|
|
177
|
+
return [`${indentOf$1(depth)}${node.name} (${node.spanId}) status=${node.status} error.type=${String(node.errorType)} duration=${node.durationMillis}ms`, ...[
|
|
178
|
+
`${indentOf$1(depth)} attrs: ${renderEntries(Object.entries(node.attributes))}`,
|
|
179
|
+
...node.events.map((event) => `${indentOf$1(depth)} event ${event.name} ${renderEntries(Object.entries(event.attributes))}`),
|
|
180
|
+
...node.links.map((link) => `${indentOf$1(depth)} link ${link.traceId}/${link.spanId}`),
|
|
181
|
+
...childrenOf(spans, node.spanId).map((child) => renderNode(spans, child, depth + 1))
|
|
182
|
+
]].join("\n");
|
|
183
|
+
};
|
|
184
|
+
const documentImpl = (observed, report) => [
|
|
185
|
+
`trace ${observed.traceId}`,
|
|
186
|
+
report,
|
|
187
|
+
...observed.spans.map((node) => renderNode(observed.spans, node, 0))
|
|
188
|
+
].join("\n");
|
|
189
|
+
const document = dual(2, documentImpl);
|
|
190
|
+
//#endregion
|
|
191
|
+
//#region src/FailureDump.ts
|
|
192
|
+
const DEFAULT_DIRECTORY = "artifacts/traces";
|
|
193
|
+
const sanitize = (value) => value.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
194
|
+
const fileNameOf = (request) => `${sanitize(request.name ?? request.traceId)}.${sanitize(request.conjunct)}.txt`;
|
|
195
|
+
const write = (request) => Effect.gen(function* () {
|
|
196
|
+
const fs = yield* FileSystem.FileSystem;
|
|
197
|
+
yield* fs.makeDirectory(DEFAULT_DIRECTORY, { recursive: true });
|
|
198
|
+
const path = `${DEFAULT_DIRECTORY}/${fileNameOf(request)}`;
|
|
199
|
+
yield* fs.writeFileString(path, document(request, request.report));
|
|
200
|
+
return path;
|
|
201
|
+
});
|
|
202
|
+
//#endregion
|
|
203
|
+
//#region src/Graph.ts
|
|
204
|
+
var Graph_exports = /* @__PURE__ */ __exportAll({
|
|
205
|
+
AttributeValue: () => AttributeValue,
|
|
206
|
+
Attributes: () => Attributes,
|
|
207
|
+
GraphNode: () => GraphNode,
|
|
208
|
+
SpanEvent: () => SpanEvent,
|
|
209
|
+
SpanLink: () => SpanLink,
|
|
210
|
+
SpanRecord: () => SpanRecord,
|
|
211
|
+
Status: () => Status,
|
|
212
|
+
TraceGraph: () => TraceGraph,
|
|
213
|
+
byId: () => byId,
|
|
214
|
+
children: () => children,
|
|
215
|
+
decode: () => decode,
|
|
216
|
+
descendants: () => descendants
|
|
217
|
+
});
|
|
241
218
|
//#endregion
|
|
242
219
|
//#region src/IncompleteObservationError.schema.ts
|
|
243
220
|
const SpanCount = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(0, { message: "a span count is a non-negative integer" })));
|
|
@@ -271,6 +248,22 @@ var Observation_service_exports = /* @__PURE__ */ __exportAll({
|
|
|
271
248
|
});
|
|
272
249
|
var Observation = class extends Context.Service()("@systemfsoftware/trace-spec/Observation") {};
|
|
273
250
|
//#endregion
|
|
251
|
+
//#region src/Verdict.schema.ts
|
|
252
|
+
const Hold = Schema.TaggedStruct("Hold", {
|
|
253
|
+
conjunct: Schema.String,
|
|
254
|
+
inspected: Schema.Array(Schema.String)
|
|
255
|
+
});
|
|
256
|
+
const Break = Schema.TaggedStruct("Break", {
|
|
257
|
+
conjunct: Schema.String,
|
|
258
|
+
inspected: Schema.Array(Schema.String),
|
|
259
|
+
detail: Schema.String
|
|
260
|
+
});
|
|
261
|
+
const Verdict = Schema.Union([Hold, Break]);
|
|
262
|
+
const isBreak = Schema.is(Break);
|
|
263
|
+
const indentOf = (depth) => " ".repeat(depth);
|
|
264
|
+
const renderBreach = (breach) => `break ${breach.conjunct} inspected=[${breach.inspected.join(", ")}]\n${indentOf(1)}${breach.detail}`;
|
|
265
|
+
const report = (verdict) => Option.map(Option.liftPredicate(verdict, isBreak), renderBreach);
|
|
266
|
+
//#endregion
|
|
274
267
|
//#region src/Contract.ts
|
|
275
268
|
var Contract_exports = /* @__PURE__ */ __exportAll({
|
|
276
269
|
BreakFailure: () => BreakFailure,
|
|
@@ -280,7 +273,7 @@ var Contract_exports = /* @__PURE__ */ __exportAll({
|
|
|
280
273
|
TransportObservationError: () => TransportObservationError,
|
|
281
274
|
TypeId: () => TypeId$3,
|
|
282
275
|
check: () => check,
|
|
283
|
-
holds: () => holds,
|
|
276
|
+
holds: () => holds$1,
|
|
284
277
|
judge: () => judge,
|
|
285
278
|
of: () => of,
|
|
286
279
|
stimulate: () => stimulate,
|
|
@@ -312,14 +305,14 @@ const of = (taxonomy) => ({
|
|
|
312
305
|
const stimulateDual = (self, stimulus) => stimulatedOf(self.taxonomy, stimulus);
|
|
313
306
|
const stimulate = dual(2, stimulateDual);
|
|
314
307
|
const holdsDual = (self, relation) => contractOf(self.taxonomy, self.stimulus, relation);
|
|
315
|
-
const holds = dual(2, holdsDual);
|
|
308
|
+
const holds$1 = dual(2, holdsDual);
|
|
316
309
|
const isContract = (value) => Predicate.hasProperty(value, TypeId$3);
|
|
317
310
|
const dumpOf = (observed, verdict, options) => Option.match(report(verdict), {
|
|
318
311
|
onNone: () => Effect.succeed(null),
|
|
319
|
-
onSome: (
|
|
312
|
+
onSome: (rendered) => Effect.map(Effect.option(write({
|
|
320
313
|
...observed,
|
|
321
314
|
conjunct: verdict.conjunct,
|
|
322
|
-
report,
|
|
315
|
+
report: rendered,
|
|
323
316
|
name: options?.dumpName
|
|
324
317
|
})), Option.getOrNull)
|
|
325
318
|
});
|
|
@@ -355,8 +348,8 @@ const reportOf = (relationId, judgment) => Match.value(judgment.verdict).pipe(Ma
|
|
|
355
348
|
].join("\n")
|
|
356
349
|
})), Match.exhaustive);
|
|
357
350
|
const verdictCheckWith = (self, expect, judgment, frame) => {
|
|
358
|
-
const
|
|
359
|
-
return
|
|
351
|
+
const finding = reportOf(self.relation.id, judgment);
|
|
352
|
+
return finding.verdict === "Break" ? Effect.die(withRaisingFrame(failureOfReport(finding), frame)) : expect(finding, finding.report).toEqual(held);
|
|
360
353
|
};
|
|
361
354
|
const verdictCheckImpl = (self, expect, judgment) => verdictCheckWith(self, expect, judgment, callFrame());
|
|
362
355
|
/**
|
|
@@ -374,10 +367,54 @@ const checkDual = (self, expect, input, options) => {
|
|
|
374
367
|
*/
|
|
375
368
|
const check = dual((args) => isContract(args[0]), checkDual);
|
|
376
369
|
//#endregion
|
|
370
|
+
//#region src/drivers/judge-tempo-answer.workflow.ts
|
|
371
|
+
const JudgeTempoAnswerTypeId = Symbol.for("@systemfsoftware/trace-spec/JudgeTempoAnswer");
|
|
372
|
+
var TempoBodyDecoded = class extends Schema.TaggedClass()("TempoBodyDecoded", {
|
|
373
|
+
spans: Schema.Array(SpanRecord),
|
|
374
|
+
status: Schema.optional(Schema.String)
|
|
375
|
+
}) {};
|
|
376
|
+
var TempoBodyUndecodable = class extends Schema.TaggedClass()("TempoBodyUndecodable", { detail: Schema.String }) {};
|
|
377
|
+
const TempoBody = Schema.Union([TempoBodyDecoded, TempoBodyUndecodable]);
|
|
378
|
+
var TempoAnswerComplete = class extends Schema.TaggedClass()("TempoAnswerComplete", { spans: Schema.Array(SpanRecord) }) {
|
|
379
|
+
[JudgeTempoAnswerTypeId] = JudgeTempoAnswerTypeId;
|
|
380
|
+
};
|
|
381
|
+
var TempoAnswerIncomplete = class extends Schema.TaggedClass()("TempoAnswerIncomplete", {
|
|
382
|
+
status: Schema.String,
|
|
383
|
+
spanCount: Schema.Int
|
|
384
|
+
}) {
|
|
385
|
+
[JudgeTempoAnswerTypeId] = JudgeTempoAnswerTypeId;
|
|
386
|
+
};
|
|
387
|
+
var TempoAnswerUndecodable = class extends Schema.TaggedClass()("TempoAnswerUndecodable", { detail: Schema.String }) {
|
|
388
|
+
[JudgeTempoAnswerTypeId] = JudgeTempoAnswerTypeId;
|
|
389
|
+
};
|
|
390
|
+
const TempoAnswerDecision = Schema.Union([
|
|
391
|
+
TempoAnswerComplete,
|
|
392
|
+
TempoAnswerIncomplete,
|
|
393
|
+
TempoAnswerUndecodable
|
|
394
|
+
]);
|
|
395
|
+
var JudgeTempoAnswer = class extends Schema.TaggedClass()("JudgeTempoAnswer", { body: TempoBody }) {
|
|
396
|
+
static [Workflow.InstrumentationBrand] = {};
|
|
397
|
+
};
|
|
398
|
+
const isComplete = (status) => Option.match(status, {
|
|
399
|
+
onNone: () => true,
|
|
400
|
+
onSome: (marked) => marked === "COMPLETE"
|
|
401
|
+
});
|
|
402
|
+
const classify$1 = (spans, status) => Match.value(isComplete(status)).pipe(Match.when(true, () => new TempoAnswerComplete({ spans })), Match.when(false, () => new TempoAnswerIncomplete({
|
|
403
|
+
status: Option.getOrElse(status, () => "INCOMPLETE"),
|
|
404
|
+
spanCount: spans.length
|
|
405
|
+
})), Match.exhaustive);
|
|
406
|
+
const decide$5 = (command) => Result$1.succeed(Match.value(command.body).pipe(Match.tag("TempoBodyDecoded", (decoded) => classify$1(decoded.spans, Option.fromUndefinedOr(decoded.status))), Match.tag("TempoBodyUndecodable", (undecodable) => new TempoAnswerUndecodable({ detail: undecodable.detail })), Match.exhaustive));
|
|
407
|
+
const judgeTempoAnswer = Workflow.make({
|
|
408
|
+
command: JudgeTempoAnswer,
|
|
409
|
+
decision: TempoAnswerDecision,
|
|
410
|
+
error: Schema.Never,
|
|
411
|
+
decide: decide$5
|
|
412
|
+
});
|
|
413
|
+
//#endregion
|
|
377
414
|
//#region src/drivers/tempo-trace.schema.ts
|
|
378
415
|
/** Proto bytes (base64 on the wire) as the lowercase hex ids traces are addressed by. */
|
|
379
416
|
const HexId = Schema.Uint8ArrayFromBase64.pipe(Schema.decodeTo(Schema.String, {
|
|
380
|
-
decode: SchemaGetter.transform(
|
|
417
|
+
decode: SchemaGetter.transform(Hex.encode),
|
|
381
418
|
encode: SchemaGetter.decodeHex()
|
|
382
419
|
}));
|
|
383
420
|
const secondsAndNanos = (nanos) => {
|
|
@@ -550,32 +587,27 @@ var tempo_trace_store_exports = /* @__PURE__ */ __exportAll({ source: () => sour
|
|
|
550
587
|
*/
|
|
551
588
|
const parseBody = Schema.decodeResult(Schema.fromJsonString(TempoV2TraceResponse));
|
|
552
589
|
const orEmpty = (values) => values ?? [];
|
|
553
|
-
const
|
|
554
|
-
const
|
|
555
|
-
|
|
556
|
-
|
|
590
|
+
const spansOf = (response) => orEmpty(response.trace.resourceSpans).flatMap((resourceSpans) => orEmpty(resourceSpans.scopeSpans).flatMap((scopeSpans) => orEmpty(scopeSpans.spans)));
|
|
591
|
+
const bodyOf = (decoded) => Result.match(decoded, {
|
|
592
|
+
onFailure: (error) => new TempoBodyUndecodable({ detail: error.message }),
|
|
593
|
+
onSuccess: (response) => new TempoBodyDecoded({
|
|
594
|
+
spans: spansOf(response),
|
|
595
|
+
status: response.status
|
|
596
|
+
})
|
|
597
|
+
});
|
|
557
598
|
const transportFailureOf = (traceId, url, cause) => new TransportObservationError({
|
|
558
599
|
traceId,
|
|
559
600
|
source: url,
|
|
560
601
|
detail: cause
|
|
561
602
|
});
|
|
562
603
|
const refusedOf = (traceId, url, error) => transportFailureOf(traceId, url, error.message);
|
|
563
|
-
const undecodableOf = (traceId, url,
|
|
604
|
+
const undecodableOf = (traceId, url, detail) => transportFailureOf(traceId, url, `undecodable trace body: ${detail}`);
|
|
564
605
|
const incompleteOf = (traceId, status, spanCount) => new IncompleteObservationError({
|
|
565
606
|
traceId,
|
|
566
607
|
spanCount,
|
|
567
608
|
detail: `the store answered ${status}: waiting cannot complete the trace`
|
|
568
609
|
});
|
|
569
|
-
const
|
|
570
|
-
const markedOf = (response) => response.status ?? "INCOMPLETE";
|
|
571
|
-
const recordsOf$1 = (traceId, response) => {
|
|
572
|
-
const spans = spansOf(response);
|
|
573
|
-
return isComplete(response.status) ? Effect.succeed(spans) : Effect.fail(incompleteOf(traceId, markedOf(response), spans.length));
|
|
574
|
-
};
|
|
575
|
-
const readTrace = (traceId, url, body) => {
|
|
576
|
-
const decoded = parseBody(body);
|
|
577
|
-
return Result.isFailure(decoded) ? Effect.fail(undecodableOf(traceId, url, decoded.failure)) : recordsOf$1(traceId, decoded.success);
|
|
578
|
-
};
|
|
610
|
+
const readTrace = (traceId, url, body) => Effect.flatMap(Effect.fromResult(judgeTempoAnswer(new JudgeTempoAnswer({ body: bodyOf(parseBody(body)) }))), (decision) => Match.value(decision).pipe(Match.tag("TempoAnswerComplete", (complete) => Effect.succeed(complete.spans)), Match.tag("TempoAnswerIncomplete", (incomplete) => Effect.fail(incompleteOf(traceId, incomplete.status, incomplete.spanCount))), Match.tag("TempoAnswerUndecodable", (undecodable) => Effect.fail(undecodableOf(traceId, url, undecodable.detail))), Match.exhaustive));
|
|
579
611
|
/** One read against one Tempo endpoint. Its only requirement is the caller's HTTP client. */
|
|
580
612
|
const source = (options) => {
|
|
581
613
|
const urlOf = (traceId) => `${options.baseUrl}/api/v2/traces/${traceId}`;
|
|
@@ -713,6 +745,199 @@ const ObservationWindows = Blueprint.make()(TypeId$1).steps({
|
|
|
713
745
|
});
|
|
714
746
|
const make$2 = (serviceName) => ObservationWindows.of(ObservationWindowSpec.make({ serviceName }));
|
|
715
747
|
//#endregion
|
|
748
|
+
//#region src/combine-any-relations.workflow.ts
|
|
749
|
+
const CombineAnyRelationsTypeId = Symbol.for("@systemfsoftware/trace-spec/CombineAnyRelations");
|
|
750
|
+
/** At least one relation held, so the disjunction holds over every inspected span. */
|
|
751
|
+
var AnyRelationHeld = class extends Schema.TaggedClass()("AnyRelationHeld", {
|
|
752
|
+
conjunct: Schema.String,
|
|
753
|
+
inspected: Schema.Array(Schema.String)
|
|
754
|
+
}) {
|
|
755
|
+
[CombineAnyRelationsTypeId] = CombineAnyRelationsTypeId;
|
|
756
|
+
};
|
|
757
|
+
/** No relation held: every conjunct is named in the break. */
|
|
758
|
+
var NoRelationHeld = class extends Schema.TaggedClass()("NoRelationHeld", {
|
|
759
|
+
conjunct: Schema.String,
|
|
760
|
+
inspected: Schema.Array(Schema.String),
|
|
761
|
+
detail: Schema.String
|
|
762
|
+
}) {
|
|
763
|
+
[CombineAnyRelationsTypeId] = CombineAnyRelationsTypeId;
|
|
764
|
+
};
|
|
765
|
+
const CombineAnyRelationsDecision = Schema.Union([AnyRelationHeld, NoRelationHeld]);
|
|
766
|
+
var CombineAnyRelations = class extends Schema.TaggedClass()("CombineAnyRelations", {
|
|
767
|
+
conjunct: Schema.String,
|
|
768
|
+
verdicts: Schema.Array(Verdict)
|
|
769
|
+
}) {
|
|
770
|
+
static [Workflow.InstrumentationBrand] = {};
|
|
771
|
+
};
|
|
772
|
+
const holds = (verdict) => Match.value(verdict).pipe(Match.tag("Hold", () => true), Match.tag("Break", () => false), Match.exhaustive);
|
|
773
|
+
const inspectedOf$1 = (verdicts) => Array$1.flatMap(verdicts, (verdict) => verdict.inspected);
|
|
774
|
+
const namedConjuncts = (verdicts) => Array$1.join(Array$1.map(verdicts, (verdict) => verdict.conjunct), ", ");
|
|
775
|
+
const decide$4 = (command) => Result$1.succeed(Match.value(Array$1.some(command.verdicts, holds)).pipe(Match.when(true, () => new AnyRelationHeld({
|
|
776
|
+
conjunct: command.conjunct,
|
|
777
|
+
inspected: inspectedOf$1(command.verdicts)
|
|
778
|
+
})), Match.when(false, () => new NoRelationHeld({
|
|
779
|
+
conjunct: command.conjunct,
|
|
780
|
+
inspected: inspectedOf$1(command.verdicts),
|
|
781
|
+
detail: namedConjuncts(command.verdicts)
|
|
782
|
+
})), Match.exhaustive));
|
|
783
|
+
/** `any(...)`: holds as soon as one relation holds, and otherwise breaks naming every conjunct. */
|
|
784
|
+
const combineAnyRelations = Workflow.make({
|
|
785
|
+
command: CombineAnyRelations,
|
|
786
|
+
decision: CombineAnyRelationsDecision,
|
|
787
|
+
error: Schema.Never,
|
|
788
|
+
decide: decide$4
|
|
789
|
+
});
|
|
790
|
+
//#endregion
|
|
791
|
+
//#region src/combine-relation-verdicts.workflow.ts
|
|
792
|
+
const CombineRelationVerdictsTypeId = Symbol.for("@systemfsoftware/trace-spec/CombineRelationVerdicts");
|
|
793
|
+
const EvaluatedRelation = Schema.Struct({
|
|
794
|
+
verdict: Verdict,
|
|
795
|
+
soft: Schema.Boolean
|
|
796
|
+
});
|
|
797
|
+
var FirstHardBreak = class extends Schema.TaggedClass()("FirstHardBreak", {
|
|
798
|
+
conjunct: Schema.String,
|
|
799
|
+
inspected: Schema.Array(Schema.String),
|
|
800
|
+
detail: Schema.String
|
|
801
|
+
}) {
|
|
802
|
+
[CombineRelationVerdictsTypeId] = CombineRelationVerdictsTypeId;
|
|
803
|
+
};
|
|
804
|
+
var AggregatedSoftBreak = class extends Schema.TaggedClass()("AggregatedSoftBreak", {
|
|
805
|
+
conjunct: Schema.String,
|
|
806
|
+
inspected: Schema.Array(Schema.String),
|
|
807
|
+
detail: Schema.String
|
|
808
|
+
}) {
|
|
809
|
+
[CombineRelationVerdictsTypeId] = CombineRelationVerdictsTypeId;
|
|
810
|
+
};
|
|
811
|
+
var EveryRelationHeld = class extends Schema.TaggedClass()("EveryRelationHeld", {
|
|
812
|
+
conjunct: Schema.String,
|
|
813
|
+
inspected: Schema.Array(Schema.String)
|
|
814
|
+
}) {
|
|
815
|
+
[CombineRelationVerdictsTypeId] = CombineRelationVerdictsTypeId;
|
|
816
|
+
};
|
|
817
|
+
const CombineRelationVerdictsDecision = Schema.Union([
|
|
818
|
+
FirstHardBreak,
|
|
819
|
+
AggregatedSoftBreak,
|
|
820
|
+
EveryRelationHeld
|
|
821
|
+
]);
|
|
822
|
+
var CombineRelationVerdicts = class extends Schema.TaggedClass()("CombineRelationVerdicts", {
|
|
823
|
+
conjunct: Schema.String,
|
|
824
|
+
verdicts: Schema.Array(EvaluatedRelation)
|
|
825
|
+
}) {
|
|
826
|
+
static [Workflow.InstrumentationBrand] = {};
|
|
827
|
+
};
|
|
828
|
+
const asBreak = (entry) => Match.value(entry.verdict).pipe(Match.tag("Break", (breach) => Option.some(breach)), Match.tag("Hold", () => Option.none()), Match.exhaustive);
|
|
829
|
+
const breaksIn = (entries) => Array$1.flatMap(entries, (entry) => Option.match(asBreak(entry), {
|
|
830
|
+
onNone: () => [],
|
|
831
|
+
onSome: (breach) => [breach]
|
|
832
|
+
}));
|
|
833
|
+
const firstHardBreak = (verdicts) => Array$1.head(breaksIn(Array$1.filter(verdicts, (entry) => !entry.soft)));
|
|
834
|
+
const softBreaks = (verdicts) => breaksIn(Array$1.filter(verdicts, (entry) => entry.soft));
|
|
835
|
+
const aggregateSoft = (command) => {
|
|
836
|
+
const breaks = softBreaks(command.verdicts);
|
|
837
|
+
return Option.match(Array$1.head(breaks), {
|
|
838
|
+
onNone: () => new EveryRelationHeld({
|
|
839
|
+
conjunct: command.conjunct,
|
|
840
|
+
inspected: []
|
|
841
|
+
}),
|
|
842
|
+
onSome: () => new AggregatedSoftBreak({
|
|
843
|
+
conjunct: command.conjunct,
|
|
844
|
+
inspected: Array$1.flatMap(breaks, (breach) => breach.inspected),
|
|
845
|
+
detail: Array$1.join(Array$1.map(breaks, (breach) => breach.conjunct), ", ")
|
|
846
|
+
})
|
|
847
|
+
});
|
|
848
|
+
};
|
|
849
|
+
const decide$3 = (command) => Result$1.succeed(Option.match(firstHardBreak(command.verdicts), {
|
|
850
|
+
onNone: () => aggregateSoft(command),
|
|
851
|
+
onSome: (winner) => new FirstHardBreak({
|
|
852
|
+
conjunct: winner.conjunct,
|
|
853
|
+
inspected: winner.inspected,
|
|
854
|
+
detail: winner.detail
|
|
855
|
+
})
|
|
856
|
+
}));
|
|
857
|
+
const combineRelationVerdicts = Workflow.make({
|
|
858
|
+
command: CombineRelationVerdicts,
|
|
859
|
+
decision: CombineRelationVerdictsDecision,
|
|
860
|
+
error: Schema.Never,
|
|
861
|
+
decide: decide$3
|
|
862
|
+
});
|
|
863
|
+
//#endregion
|
|
864
|
+
//#region src/judge-edge-placement.workflow.ts
|
|
865
|
+
const JudgeEdgePlacementTypeId = Symbol.for("@systemfsoftware/trace-spec/JudgeEdgePlacement");
|
|
866
|
+
var EdgePlacementHeld = class extends Schema.TaggedClass()("EdgePlacementHeld", {
|
|
867
|
+
conjunct: Schema.String,
|
|
868
|
+
inspected: Schema.Array(Schema.String)
|
|
869
|
+
}) {
|
|
870
|
+
[JudgeEdgePlacementTypeId] = JudgeEdgePlacementTypeId;
|
|
871
|
+
};
|
|
872
|
+
var EdgePlacementBroken = class extends Schema.TaggedClass()("EdgePlacementBroken", {
|
|
873
|
+
conjunct: Schema.String,
|
|
874
|
+
inspected: Schema.Array(Schema.String),
|
|
875
|
+
detail: Schema.String
|
|
876
|
+
}) {
|
|
877
|
+
[JudgeEdgePlacementTypeId] = JudgeEdgePlacementTypeId;
|
|
878
|
+
};
|
|
879
|
+
const JudgeEdgePlacementDecision = Schema.Union([EdgePlacementHeld, EdgePlacementBroken]);
|
|
880
|
+
var JudgeEdgePlacement = class extends Schema.TaggedClass()("JudgeEdgePlacement", {
|
|
881
|
+
conjunct: Schema.String,
|
|
882
|
+
placed: Schema.Array(Schema.String),
|
|
883
|
+
reached: Schema.Array(Schema.String),
|
|
884
|
+
detail: Schema.String
|
|
885
|
+
}) {
|
|
886
|
+
static [Workflow.InstrumentationBrand] = {};
|
|
887
|
+
};
|
|
888
|
+
const everyPlaced = (placed, reached) => Array$1.every(placed, (spanId) => Array$1.some(reached, (candidate) => candidate === spanId));
|
|
889
|
+
const decide$2 = (command) => Result$1.succeed(Match.value(everyPlaced(command.placed, command.reached)).pipe(Match.when(true, () => new EdgePlacementHeld({
|
|
890
|
+
conjunct: command.conjunct,
|
|
891
|
+
inspected: command.placed
|
|
892
|
+
})), Match.when(false, () => new EdgePlacementBroken({
|
|
893
|
+
conjunct: command.conjunct,
|
|
894
|
+
inspected: command.placed,
|
|
895
|
+
detail: command.detail
|
|
896
|
+
})), Match.exhaustive));
|
|
897
|
+
const judgeEdgePlacement = Workflow.make({
|
|
898
|
+
command: JudgeEdgePlacement,
|
|
899
|
+
decision: JudgeEdgePlacementDecision,
|
|
900
|
+
error: Schema.Never,
|
|
901
|
+
decide: decide$2
|
|
902
|
+
});
|
|
903
|
+
//#endregion
|
|
904
|
+
//#region src/negate-relation-verdict.workflow.ts
|
|
905
|
+
const NegateRelationVerdictTypeId = Symbol.for("@systemfsoftware/trace-spec/NegateRelationVerdict");
|
|
906
|
+
var HoldNegated = class extends Schema.TaggedClass()("HoldNegated", {
|
|
907
|
+
conjunct: Schema.String,
|
|
908
|
+
inspected: Schema.Array(Schema.String),
|
|
909
|
+
detail: Schema.String
|
|
910
|
+
}) {
|
|
911
|
+
[NegateRelationVerdictTypeId] = NegateRelationVerdictTypeId;
|
|
912
|
+
};
|
|
913
|
+
var BreakNegated = class extends Schema.TaggedClass()("BreakNegated", {
|
|
914
|
+
conjunct: Schema.String,
|
|
915
|
+
inspected: Schema.Array(Schema.String)
|
|
916
|
+
}) {
|
|
917
|
+
[NegateRelationVerdictTypeId] = NegateRelationVerdictTypeId;
|
|
918
|
+
};
|
|
919
|
+
const NegateRelationVerdictDecision = Schema.Union([HoldNegated, BreakNegated]);
|
|
920
|
+
var NegateRelationVerdict = class extends Schema.TaggedClass()("NegateRelationVerdict", {
|
|
921
|
+
conjunct: Schema.String,
|
|
922
|
+
verdict: Verdict
|
|
923
|
+
}) {
|
|
924
|
+
static [Workflow.InstrumentationBrand] = {};
|
|
925
|
+
};
|
|
926
|
+
const decide$1 = (command) => Result$1.succeed(Match.value(command.verdict).pipe(Match.tag("Hold", (held) => new HoldNegated({
|
|
927
|
+
conjunct: command.conjunct,
|
|
928
|
+
inspected: held.inspected,
|
|
929
|
+
detail: `${held.conjunct} held`
|
|
930
|
+
})), Match.tag("Break", (breach) => new BreakNegated({
|
|
931
|
+
conjunct: command.conjunct,
|
|
932
|
+
inspected: breach.inspected
|
|
933
|
+
})), Match.exhaustive));
|
|
934
|
+
const negateRelationVerdict = Workflow.make({
|
|
935
|
+
command: NegateRelationVerdict,
|
|
936
|
+
decision: NegateRelationVerdictDecision,
|
|
937
|
+
error: Schema.Never,
|
|
938
|
+
decide: decide$1
|
|
939
|
+
});
|
|
940
|
+
//#endregion
|
|
716
941
|
//#region src/Rel.ts
|
|
717
942
|
var Rel_exports = /* @__PURE__ */ __exportAll({
|
|
718
943
|
Break: () => Break,
|
|
@@ -736,6 +961,10 @@ var Rel_exports = /* @__PURE__ */ __exportAll({
|
|
|
736
961
|
status: () => status,
|
|
737
962
|
unique: () => unique
|
|
738
963
|
});
|
|
964
|
+
const decisionOf = (result) => Result.match(result, {
|
|
965
|
+
onFailure: (unreachable) => absurd(unreachable),
|
|
966
|
+
onSuccess: (decision) => decision
|
|
967
|
+
});
|
|
739
968
|
const relation = (parts) => Object.assign((graph) => parts.evaluate(graph), {
|
|
740
969
|
id: parts.id,
|
|
741
970
|
soft: parts.soft,
|
|
@@ -744,9 +973,7 @@ const relation = (parts) => Object.assign((graph) => parts.evaluate(graph), {
|
|
|
744
973
|
const matchedNodes = (graph, spec) => byId(graph, spec);
|
|
745
974
|
const inspectedOf = (nodes) => nodes.map((node) => node.spanId);
|
|
746
975
|
const matchedAll = (items, predicate) => items.length > 0 && items.every(predicate);
|
|
747
|
-
const
|
|
748
|
-
const isHold$1 = (verdict) => Schema.is(Hold)(verdict);
|
|
749
|
-
const verdictOf$1 = (options) => options.holds ? Hold.make({
|
|
976
|
+
const verdictOf = (options) => options.holds ? Hold.make({
|
|
750
977
|
conjunct: options.id,
|
|
751
978
|
inspected: options.inspected
|
|
752
979
|
}) : Break.make({
|
|
@@ -760,7 +987,7 @@ const declared$1 = (declaration) => relation({
|
|
|
760
987
|
softenable: declaration.softenable,
|
|
761
988
|
evaluate: (graph) => {
|
|
762
989
|
const inspected = declaration.spans.flatMap((span) => inspectedOf(byId(graph, span)));
|
|
763
|
-
return verdictOf
|
|
990
|
+
return verdictOf({
|
|
764
991
|
id: declaration.id,
|
|
765
992
|
inspected,
|
|
766
993
|
holds: declaration.holds(graph),
|
|
@@ -873,7 +1100,7 @@ const forallImpl = (spec, predicate, detail) => {
|
|
|
873
1100
|
softenable: true,
|
|
874
1101
|
evaluate: (graph) => {
|
|
875
1102
|
const nodes = matchedNodes(graph, spec);
|
|
876
|
-
return verdictOf
|
|
1103
|
+
return verdictOf({
|
|
877
1104
|
id,
|
|
878
1105
|
inspected: inspectedOf(nodes),
|
|
879
1106
|
holds: matchedAll(nodes, predicate),
|
|
@@ -889,13 +1116,16 @@ const soft = (self) => self.softenable ? relation({
|
|
|
889
1116
|
softenable: true,
|
|
890
1117
|
evaluate: (graph) => self(graph)
|
|
891
1118
|
}) : self;
|
|
892
|
-
const negatedVerdict = (id, inner) => Match.value(
|
|
1119
|
+
const negatedVerdict = (id, inner) => Match.value(decisionOf(negateRelationVerdict(new NegateRelationVerdict({
|
|
893
1120
|
conjunct: id,
|
|
1121
|
+
verdict: inner
|
|
1122
|
+
})))).pipe(Match.tag("HoldNegated", (held) => Break.make({
|
|
1123
|
+
conjunct: held.conjunct,
|
|
894
1124
|
inspected: held.inspected,
|
|
895
|
-
detail:
|
|
896
|
-
})), Match.tag("
|
|
897
|
-
conjunct:
|
|
898
|
-
inspected:
|
|
1125
|
+
detail: held.detail
|
|
1126
|
+
})), Match.tag("BreakNegated", (broken) => Hold.make({
|
|
1127
|
+
conjunct: broken.conjunct,
|
|
1128
|
+
inspected: broken.inspected
|
|
899
1129
|
})), Match.exhaustive);
|
|
900
1130
|
const not = (self) => {
|
|
901
1131
|
const id = `not(${self.id})`;
|
|
@@ -906,24 +1136,29 @@ const not = (self) => {
|
|
|
906
1136
|
evaluate: (graph) => negatedVerdict(id, self(graph))
|
|
907
1137
|
});
|
|
908
1138
|
};
|
|
909
|
-
const
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
})
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
|
|
1139
|
+
const combinationOf = (conjunct, relations, graph) => Match.value(decisionOf(combineRelationVerdicts(new CombineRelationVerdicts({
|
|
1140
|
+
conjunct,
|
|
1141
|
+
verdicts: relations.map((relation) => ({
|
|
1142
|
+
verdict: relation(graph),
|
|
1143
|
+
soft: relation.soft
|
|
1144
|
+
}))
|
|
1145
|
+
})))).pipe(Match.tag("FirstHardBreak", (winner) => Break.make({
|
|
1146
|
+
conjunct: winner.conjunct,
|
|
1147
|
+
inspected: winner.inspected,
|
|
1148
|
+
detail: winner.detail
|
|
1149
|
+
})), Match.tag("AggregatedSoftBreak", (aggregated) => Break.make({
|
|
1150
|
+
conjunct: aggregated.conjunct,
|
|
1151
|
+
inspected: aggregated.inspected,
|
|
1152
|
+
detail: aggregated.detail
|
|
1153
|
+
})), Match.tag("EveryRelationHeld", (held) => Hold.make({
|
|
1154
|
+
conjunct: held.conjunct,
|
|
1155
|
+
inspected: held.inspected
|
|
1156
|
+
})), Match.exhaustive);
|
|
922
1157
|
const combined = (options) => relation({
|
|
923
1158
|
id: options.id,
|
|
924
1159
|
soft: options.soft,
|
|
925
1160
|
softenable: options.softenable,
|
|
926
|
-
evaluate: (graph) =>
|
|
1161
|
+
evaluate: (graph) => combinationOf(options.id, options.relations, graph)
|
|
927
1162
|
});
|
|
928
1163
|
const all = (...relations) => combined({
|
|
929
1164
|
id: `all(${relations.map((relation) => relation.id).join(", ")})`,
|
|
@@ -931,30 +1166,43 @@ const all = (...relations) => combined({
|
|
|
931
1166
|
soft: relations.every((relation) => relation.soft),
|
|
932
1167
|
softenable: true
|
|
933
1168
|
});
|
|
1169
|
+
const disjunctionOf = (conjunct, verdicts) => Match.value(decisionOf(combineAnyRelations(new CombineAnyRelations({
|
|
1170
|
+
conjunct,
|
|
1171
|
+
verdicts
|
|
1172
|
+
})))).pipe(Match.tag("AnyRelationHeld", (held) => Hold.make({
|
|
1173
|
+
conjunct: held.conjunct,
|
|
1174
|
+
inspected: held.inspected
|
|
1175
|
+
})), Match.tag("NoRelationHeld", (broken) => Break.make({
|
|
1176
|
+
conjunct: broken.conjunct,
|
|
1177
|
+
inspected: broken.inspected,
|
|
1178
|
+
detail: broken.detail
|
|
1179
|
+
})), Match.exhaustive);
|
|
934
1180
|
const any = (...relations) => {
|
|
935
1181
|
const id = `any(${relations.map((relation) => relation.id).join(", ")})`;
|
|
936
1182
|
return relation({
|
|
937
1183
|
id,
|
|
938
1184
|
soft: false,
|
|
939
1185
|
softenable: false,
|
|
940
|
-
evaluate: (graph) =>
|
|
941
|
-
const verdicts = relations.map((relation) => relation(graph));
|
|
942
|
-
const inspected = verdicts.flatMap((verdict) => verdict.inspected);
|
|
943
|
-
return verdicts.some(isHold$1) ? Hold.make({
|
|
944
|
-
conjunct: id,
|
|
945
|
-
inspected
|
|
946
|
-
}) : Break.make({
|
|
947
|
-
conjunct: id,
|
|
948
|
-
inspected,
|
|
949
|
-
detail: verdicts.map((verdict) => verdict.conjunct).join(", ")
|
|
950
|
-
});
|
|
951
|
-
}
|
|
1186
|
+
evaluate: (graph) => disjunctionOf(id, relations.map((relation) => relation(graph)))
|
|
952
1187
|
});
|
|
953
1188
|
};
|
|
954
1189
|
const REACH_BY_RELATION = {
|
|
955
1190
|
child: childIdsOf,
|
|
956
1191
|
descendant: descendantIdsOf
|
|
957
1192
|
};
|
|
1193
|
+
const placementVerdictOf = (conjunct, placed, reached, detail) => Match.value(decisionOf(judgeEdgePlacement(new JudgeEdgePlacement({
|
|
1194
|
+
conjunct,
|
|
1195
|
+
placed,
|
|
1196
|
+
reached: [...reached],
|
|
1197
|
+
detail
|
|
1198
|
+
})))).pipe(Match.tag("EdgePlacementHeld", (held) => Hold.make({
|
|
1199
|
+
conjunct: held.conjunct,
|
|
1200
|
+
inspected: held.inspected
|
|
1201
|
+
})), Match.tag("EdgePlacementBroken", (broken) => Break.make({
|
|
1202
|
+
conjunct: broken.conjunct,
|
|
1203
|
+
inspected: broken.inspected,
|
|
1204
|
+
detail: broken.detail
|
|
1205
|
+
})), Match.exhaustive);
|
|
958
1206
|
const placementOf = (edge) => {
|
|
959
1207
|
const id = `placement(${edge.relation}:${edge.parent.id},${edge.child.id})`;
|
|
960
1208
|
return relation({
|
|
@@ -962,14 +1210,9 @@ const placementOf = (edge) => {
|
|
|
962
1210
|
soft: false,
|
|
963
1211
|
softenable: false,
|
|
964
1212
|
evaluate: (graph) => {
|
|
965
|
-
const placed = matchedNodes(graph, edge.child);
|
|
1213
|
+
const placed = inspectedOf(matchedNodes(graph, edge.child));
|
|
966
1214
|
const reached = REACH_BY_RELATION[edge.relation](graph, matchedNodes(graph, edge.parent));
|
|
967
|
-
return
|
|
968
|
-
id,
|
|
969
|
-
inspected: inspectedOf(placed),
|
|
970
|
-
holds: placed.every((node) => reached.has(node.spanId)),
|
|
971
|
-
detail: `a ${edge.child.id} span is not a ${edge.relation} of any ${edge.parent.id} span`
|
|
972
|
-
});
|
|
1215
|
+
return placementVerdictOf(id, placed, reached, `a ${edge.child.id} span is not a ${edge.relation} of any ${edge.parent.id} span`);
|
|
973
1216
|
}
|
|
974
1217
|
});
|
|
975
1218
|
};
|
|
@@ -986,44 +1229,87 @@ const fromTaxonomyImpl = (taxonomy, options) => combined({
|
|
|
986
1229
|
});
|
|
987
1230
|
const fromTaxonomy = dual(2, fromTaxonomyImpl);
|
|
988
1231
|
//#endregion
|
|
1232
|
+
//#region src/settle-remote-read.workflow.ts
|
|
1233
|
+
const SettleRemoteReadTypeId = Symbol.for("@systemfsoftware/trace-spec/SettleRemoteRead");
|
|
1234
|
+
const ObservedSpans = Schema.Struct({
|
|
1235
|
+
spans: Schema.Array(SpanRecord),
|
|
1236
|
+
addedAtMillis: Schema.Finite
|
|
1237
|
+
});
|
|
1238
|
+
var ReadSettled = class extends Schema.TaggedClass()("ReadSettled", { observation: ObservedSpans }) {
|
|
1239
|
+
[SettleRemoteReadTypeId] = SettleRemoteReadTypeId;
|
|
1240
|
+
};
|
|
1241
|
+
var ReadAbsent = class extends Schema.TaggedClass()("ReadAbsent", { observation: ObservedSpans }) {
|
|
1242
|
+
[SettleRemoteReadTypeId] = SettleRemoteReadTypeId;
|
|
1243
|
+
};
|
|
1244
|
+
var ReadUnfinished = class extends Schema.TaggedClass()("ReadUnfinished", { observation: ObservedSpans }) {
|
|
1245
|
+
[SettleRemoteReadTypeId] = SettleRemoteReadTypeId;
|
|
1246
|
+
};
|
|
1247
|
+
var ReadStillGrowing = class extends Schema.TaggedClass()("ReadStillGrowing", { observation: ObservedSpans }) {
|
|
1248
|
+
[SettleRemoteReadTypeId] = SettleRemoteReadTypeId;
|
|
1249
|
+
};
|
|
1250
|
+
const SettleRemoteReadDecision = Schema.Union([
|
|
1251
|
+
ReadSettled,
|
|
1252
|
+
ReadAbsent,
|
|
1253
|
+
ReadUnfinished,
|
|
1254
|
+
ReadStillGrowing
|
|
1255
|
+
]);
|
|
1256
|
+
var SettleRemoteRead = class extends Schema.TaggedClass()("SettleRemoteRead", {
|
|
1257
|
+
observed: ObservedSpans,
|
|
1258
|
+
read: Schema.Array(SpanRecord),
|
|
1259
|
+
elapsedMillis: Schema.Finite,
|
|
1260
|
+
settleMillis: Schema.Finite,
|
|
1261
|
+
timeoutMillis: Schema.Finite
|
|
1262
|
+
}) {
|
|
1263
|
+
static [Workflow.InstrumentationBrand] = {};
|
|
1264
|
+
};
|
|
1265
|
+
const sameId = (left, right) => left.spanId === right.spanId;
|
|
1266
|
+
const firstOfEachId = (read) => Array$1.dedupeWith(read, sameId);
|
|
1267
|
+
const freshOf = (observed, read) => Array$1.filter(firstOfEachId(read), (span) => Array$1.every(observed.spans, (seen) => seen.spanId !== span.spanId));
|
|
1268
|
+
const absorbed = (observed, read, elapsedMillis) => {
|
|
1269
|
+
const fresh = freshOf(observed, read);
|
|
1270
|
+
return Option.match(Array$1.head(fresh), {
|
|
1271
|
+
onNone: () => observed,
|
|
1272
|
+
onSome: () => ({
|
|
1273
|
+
spans: [...observed.spans, ...fresh],
|
|
1274
|
+
addedAtMillis: elapsedMillis
|
|
1275
|
+
})
|
|
1276
|
+
});
|
|
1277
|
+
};
|
|
1278
|
+
const quietForLongEnough = (observed, elapsedMillis, settleMillis) => Array$1.every([observed.spans.length > 0, elapsedMillis - observed.addedAtMillis >= settleMillis], Boolean);
|
|
1279
|
+
const classify = (observation, elapsedMillis, settleMillis, timeoutMillis) => Match.value(quietForLongEnough(observation, elapsedMillis, settleMillis)).pipe(Match.when(true, () => new ReadSettled({ observation })), Match.when(false, () => Match.value(elapsedMillis >= timeoutMillis).pipe(Match.when(true, () => Match.value(observation.spans.length === 0).pipe(Match.when(true, () => new ReadAbsent({ observation })), Match.when(false, () => new ReadUnfinished({ observation })), Match.exhaustive)), Match.when(false, () => new ReadStillGrowing({ observation })), Match.exhaustive)), Match.exhaustive);
|
|
1280
|
+
const decide = (command) => Result$1.succeed(classify(absorbed(command.observed, command.read, command.elapsedMillis), command.elapsedMillis, command.settleMillis, command.timeoutMillis));
|
|
1281
|
+
const settleRemoteRead = Workflow.make({
|
|
1282
|
+
command: SettleRemoteRead,
|
|
1283
|
+
decision: SettleRemoteReadDecision,
|
|
1284
|
+
error: Schema.Never,
|
|
1285
|
+
decide
|
|
1286
|
+
});
|
|
1287
|
+
//#endregion
|
|
989
1288
|
//#region src/RemoteObservation.ts
|
|
990
1289
|
var RemoteObservation_exports = /* @__PURE__ */ __exportAll({ layer: () => layer });
|
|
991
1290
|
const NEVER_READ = {
|
|
992
1291
|
spans: [],
|
|
993
1292
|
addedAtMillis: 0
|
|
994
1293
|
};
|
|
995
|
-
const
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
const freshOf = (settlement, read) => {
|
|
1000
|
-
const known = idsOf(settlement.spans);
|
|
1001
|
-
return firstOfEachId(read).filter((span) => !known.has(span.spanId));
|
|
1002
|
-
};
|
|
1003
|
-
const absorbed = (settlement, read, elapsedMillis) => {
|
|
1004
|
-
const fresh = freshOf(settlement, read);
|
|
1005
|
-
return fresh.length === 0 ? settlement : {
|
|
1006
|
-
spans: [...settlement.spans, ...fresh],
|
|
1007
|
-
addedAtMillis: elapsedMillis
|
|
1008
|
-
};
|
|
1009
|
-
};
|
|
1010
|
-
const quietForLongEnough = (settlement, elapsedMillis, windows) => settlement.spans.length > 0 && elapsedMillis - settlement.addedAtMillis >= windows.settleMillis;
|
|
1294
|
+
const settlementOf = (command) => Result.match(settleRemoteRead(command), {
|
|
1295
|
+
onFailure: (unreachable) => absurd(unreachable),
|
|
1296
|
+
onSuccess: (decision) => decision
|
|
1297
|
+
});
|
|
1011
1298
|
const pastDeadline = (elapsedMillis, windows) => elapsedMillis >= windows.timeoutMillis;
|
|
1012
1299
|
const settledVerdict = (spans) => Option.some(Result.succeed(spans));
|
|
1013
1300
|
const refusedVerdict = (refusal) => Option.some(Result.fail(refusal));
|
|
1014
|
-
const
|
|
1015
|
-
quiet: quietForLongEnough(settlement, elapsedMillis, windows),
|
|
1016
|
-
vacant: settlement.spans.length === 0,
|
|
1017
|
-
late: pastDeadline(elapsedMillis, windows)
|
|
1018
|
-
}).pipe(Match.when({ quiet: true }, () => settledVerdict(settlement.spans)), Match.when({
|
|
1019
|
-
vacant: true,
|
|
1020
|
-
late: true
|
|
1021
|
-
}, () => refusedVerdict("absent")), Match.when({ late: true }, () => refusedVerdict("unfinished")), Match.orElse(() => Option.none()));
|
|
1301
|
+
const verdictOfOutcome = (outcome) => Match.value(outcome).pipe(Match.tag("ReadSettled", (settled) => settledVerdict(settled.observation.spans)), Match.tag("ReadAbsent", () => refusedVerdict("absent")), Match.tag("ReadUnfinished", () => refusedVerdict("unfinished")), Match.tag("ReadStillGrowing", () => Option.none()), Match.exhaustive);
|
|
1022
1302
|
const settleStep = (settlement, read, elapsedMillis, windows) => {
|
|
1023
|
-
const
|
|
1303
|
+
const outcome = settlementOf(new SettleRemoteRead({
|
|
1304
|
+
observed: settlement,
|
|
1305
|
+
read,
|
|
1306
|
+
elapsedMillis,
|
|
1307
|
+
settleMillis: windows.settleMillis,
|
|
1308
|
+
timeoutMillis: windows.timeoutMillis
|
|
1309
|
+
}));
|
|
1024
1310
|
return {
|
|
1025
|
-
settlement:
|
|
1026
|
-
verdict:
|
|
1311
|
+
settlement: outcome.observation,
|
|
1312
|
+
verdict: verdictOfOutcome(outcome)
|
|
1027
1313
|
};
|
|
1028
1314
|
};
|
|
1029
1315
|
const lateRefusal = (settlement) => settlement.spans.length === 0 ? "absent" : "unfinished";
|
|
@@ -1147,6 +1433,17 @@ const HarnessFailure = Schema.Union([
|
|
|
1147
1433
|
TransportObservationError
|
|
1148
1434
|
]);
|
|
1149
1435
|
//#endregion
|
|
1436
|
+
//#region src/StimulusFailure.schema.ts
|
|
1437
|
+
const firstLine = (text) => text.split("\n")[0] ?? "";
|
|
1438
|
+
var StimulusFailure = class extends Schema.TaggedError()("StimulusFailure", {
|
|
1439
|
+
stimulus: Schema.String,
|
|
1440
|
+
detail: Schema.String
|
|
1441
|
+
}) {
|
|
1442
|
+
get message() {
|
|
1443
|
+
return `The stimulus "${this.stimulus}" failed: ${firstLine(this.detail)}`;
|
|
1444
|
+
}
|
|
1445
|
+
};
|
|
1446
|
+
//#endregion
|
|
1150
1447
|
//#region src/TaskAnnounce.ts
|
|
1151
1448
|
const forget = (annotation) => {
|
|
1152
1449
|
Promise.resolve(annotation);
|
|
@@ -1169,40 +1466,6 @@ const announceDump = (judged) => Option.match(dumpMessageOf(judged), {
|
|
|
1169
1466
|
onSome: (message) => record(message, "info")
|
|
1170
1467
|
});
|
|
1171
1468
|
//#endregion
|
|
1172
|
-
//#region src/Prop.ts
|
|
1173
|
-
const isHold = Schema.is(Hold);
|
|
1174
|
-
/**
|
|
1175
|
-
* The contract with its stimulus replaced by the function the property was handed: the impostor gate
|
|
1176
|
-
* swaps in a constant fake, so the judgement must reach the stimulus through the argument, never the
|
|
1177
|
-
* closure.
|
|
1178
|
-
*/
|
|
1179
|
-
const judgedOver = (contract, subject) => ({
|
|
1180
|
-
...contract,
|
|
1181
|
-
stimulus: subject
|
|
1182
|
-
});
|
|
1183
|
-
/**
|
|
1184
|
-
* The run must be the run of the generated input: a stimulus that ignores its input and answers with one
|
|
1185
|
-
* frozen run satisfies every relation about that run, so the input pin is what refutes it.
|
|
1186
|
-
*/
|
|
1187
|
-
const consumedInput = (judgment, input) => judgment.run.input === input;
|
|
1188
|
-
const predicateImpl = (title, contract, scenario, shared) => {
|
|
1189
|
-
const provided = scenario.pipe(Layer.provideMerge(shared));
|
|
1190
|
-
const checked = (subject, input) => judge(judgedOver(contract, subject), input, { dumpName: title }).pipe(Effect.tap(announceDump), Effect.map((judgment) => isHold(judgment.verdict) && consumedInput(judgment, input)), Effect.provide(Layer.fresh(provided)));
|
|
1191
|
-
return (subject, input) => checked(subject, input);
|
|
1192
|
-
};
|
|
1193
|
-
const predicate = dual(4, predicateImpl);
|
|
1194
|
-
//#endregion
|
|
1195
|
-
//#region src/StimulusFailure.schema.ts
|
|
1196
|
-
const firstLine = (text) => text.split("\n")[0] ?? "";
|
|
1197
|
-
var StimulusFailure = class extends Schema.TaggedError()("StimulusFailure", {
|
|
1198
|
-
stimulus: Schema.String,
|
|
1199
|
-
detail: Schema.String
|
|
1200
|
-
}) {
|
|
1201
|
-
get message() {
|
|
1202
|
-
return `The stimulus "${this.stimulus}" failed: ${firstLine(this.detail)}`;
|
|
1203
|
-
}
|
|
1204
|
-
};
|
|
1205
|
-
//#endregion
|
|
1206
1469
|
//#region src/Suite.ts
|
|
1207
1470
|
var Suite_exports = /* @__PURE__ */ __exportAll({
|
|
1208
1471
|
StimulusFailure: () => StimulusFailure,
|
|
@@ -1230,6 +1493,17 @@ const caseFailureOf = (stimulus, salt) => (failure) => isHarnessFailure(failure)
|
|
|
1230
1493
|
detail: `${Cause.pretty(Cause.fail(failure))}\nrandom salt: ${salt}`
|
|
1231
1494
|
});
|
|
1232
1495
|
const caseBody = (expect, contract, input, salt) => judge(contract, input).pipe(Effect.tap(announceDump), Effect.flatMap((judgment) => verdictCheck(contract, expect, judgment)), Effect.mapError(caseFailureOf(contract.stimulus.name, salt)));
|
|
1496
|
+
const isHold = Schema.is(Hold);
|
|
1497
|
+
const judgedOver = (contract, subject) => ({
|
|
1498
|
+
...contract,
|
|
1499
|
+
stimulus: subject
|
|
1500
|
+
});
|
|
1501
|
+
const consumedInput = (judgment, input) => judgment.run.input === input;
|
|
1502
|
+
const casePredicate = (title, contract, scenario, shared) => {
|
|
1503
|
+
const provided = scenario.pipe(Layer.provideMerge(shared));
|
|
1504
|
+
const checked = (subject, input) => judge(judgedOver(contract, subject), input, { dumpName: title }).pipe(Effect.tap(announceDump), Effect.map((judgment) => isHold(judgment.verdict) && consumedInput(judgment, input)), Effect.provide(Layer.fresh(provided)));
|
|
1505
|
+
return (subject, input) => checked(subject, input);
|
|
1506
|
+
};
|
|
1233
1507
|
const caseTools = (register, propIt, scenario, shared) => {
|
|
1234
1508
|
const Case = (name, contract, input) => {
|
|
1235
1509
|
const salt = saltOf();
|
|
@@ -1240,7 +1514,7 @@ const caseTools = (register, propIt, scenario, shared) => {
|
|
|
1240
1514
|
propIt.effect.prop(name, {
|
|
1241
1515
|
of: [arbitrary],
|
|
1242
1516
|
subject: contract.stimulus
|
|
1243
|
-
}, (subject, values) =>
|
|
1517
|
+
}, (subject, values) => casePredicate(name, contract, scenario, shared)(subject, values[0]).pipe(Random.withSeed(salt)));
|
|
1244
1518
|
};
|
|
1245
1519
|
return { Case };
|
|
1246
1520
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@systemfsoftware/trace-spec",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"author": "Ryan Lee <drdgvhbh@gmail.com>",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -33,27 +33,34 @@
|
|
|
33
33
|
"dist"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@effect/opentelemetry": "4
|
|
36
|
+
"@effect/opentelemetry": "^4",
|
|
37
37
|
"@opentelemetry/api": "^1.9.0",
|
|
38
38
|
"@opentelemetry/resources": "^2",
|
|
39
39
|
"@opentelemetry/sdk-trace-base": "^2",
|
|
40
40
|
"@opentelemetry/semantic-conventions": "^1.33",
|
|
41
|
-
"@systemfsoftware/effect-cell-types": "^
|
|
42
|
-
"@systemfsoftware/effect-spec-runtime": "^0.
|
|
43
|
-
"@systemfsoftware/trace-taxonomy": "^0.0
|
|
41
|
+
"@systemfsoftware/effect-cell-types": "^12.0.0",
|
|
42
|
+
"@systemfsoftware/effect-spec-runtime": "^1.0.0",
|
|
43
|
+
"@systemfsoftware/trace-taxonomy": "^1.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@effect/platform-node": "4
|
|
46
|
+
"@effect/platform-node": "^4",
|
|
47
47
|
"@systemfsoftware/arethetypeswrong-cli": "^4.2.0",
|
|
48
|
-
"@systemfsoftware/conformance-spec": "^0.
|
|
49
|
-
"@systemfsoftware/effect-gherkin-spec": "^
|
|
50
|
-
"@systemfsoftware/oxlint-config-recommended": "^
|
|
48
|
+
"@systemfsoftware/conformance-spec": "^1.0.0",
|
|
49
|
+
"@systemfsoftware/effect-gherkin-spec": "^7.0.0",
|
|
50
|
+
"@systemfsoftware/oxlint-config-recommended": "^4.0.0",
|
|
51
|
+
"@systemfsoftware/stryker-config": "^0.1.0",
|
|
52
|
+
"@systemfsoftware/stryker-ignorer-effect-schema-declarations": "latest",
|
|
53
|
+
"@systemfsoftware/stryker-ignorer-in-source-vitest-block": "latest",
|
|
54
|
+
"@systemfsoftware/stryker-js": "latest",
|
|
55
|
+
"@systemfsoftware/stryker-js-typescript-checker": "latest",
|
|
56
|
+
"@systemfsoftware/stryker-js-vitest-runner": "latest",
|
|
57
|
+
"@systemfsoftware/stryker-test-contribution": "latest",
|
|
51
58
|
"@systemfsoftware/tsconfig": "^2.0.1",
|
|
52
59
|
"@systemfsoftware/tsdown-config": "^0.1.0",
|
|
53
|
-
"@systemfsoftware/vitest": "^0.
|
|
60
|
+
"@systemfsoftware/vitest": "^1.0.0",
|
|
54
61
|
"@systemfsoftware/vitest-config": "^0.1.0",
|
|
55
62
|
"@types/node": "^26",
|
|
56
|
-
"effect": "4
|
|
63
|
+
"effect": "^4",
|
|
57
64
|
"oxlint": "~1.82.0",
|
|
58
65
|
"rimraf": "^6.1.3",
|
|
59
66
|
"tsdown": "^0.23.0",
|
|
@@ -61,8 +68,8 @@
|
|
|
61
68
|
"vitest": "^5"
|
|
62
69
|
},
|
|
63
70
|
"peerDependencies": {
|
|
64
|
-
"@systemfsoftware/vitest": "^0.
|
|
65
|
-
"effect": "4
|
|
71
|
+
"@systemfsoftware/vitest": "^1.0.0",
|
|
72
|
+
"effect": "^4",
|
|
66
73
|
"vitest": "^5"
|
|
67
74
|
},
|
|
68
75
|
"publishConfig": {
|
|
@@ -74,6 +81,8 @@
|
|
|
74
81
|
"build": "tsdown -l warn",
|
|
75
82
|
"typecheck": "tsc -b",
|
|
76
83
|
"test": "vitest run",
|
|
84
|
+
"mutation": "stryker run",
|
|
85
|
+
"mutation:full": "stryker run --force",
|
|
77
86
|
"test:types": "TSTYCHE_TYPESCRIPT_MODULE=tstyche-typescript tstyche",
|
|
78
87
|
"lint": "f=${OXLINT_FORMAT:-${AGENT:+agent}}; oxlint . --format=${f:-default}",
|
|
79
88
|
"attw": "attw --pack ."
|