@ontrails/core 0.2.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 +849 -0
- package/README.md +190 -0
- package/package.json +36 -0
- package/src/activation-provenance.ts +116 -0
- package/src/activation-source-compatibility.ts +430 -0
- package/src/activation-source-derivation.ts +227 -0
- package/src/activation-source.ts +93 -0
- package/src/blob-ref.ts +90 -0
- package/src/branded.ts +135 -0
- package/src/collections.ts +99 -0
- package/src/compose-batch.ts +69 -0
- package/src/compose-schema.ts +36 -0
- package/src/context.ts +66 -0
- package/src/derive.ts +485 -0
- package/src/detours.ts +8 -0
- package/src/diagnostics.ts +21 -0
- package/src/draft.ts +350 -0
- package/src/entity.ts +346 -0
- package/src/error-rendering.ts +87 -0
- package/src/errors.ts +483 -0
- package/src/execute.ts +1577 -0
- package/src/fetch.ts +138 -0
- package/src/fire.ts +1172 -0
- package/src/glob.ts +81 -0
- package/src/guards.ts +37 -0
- package/src/index.ts +704 -0
- package/src/internal/fork-ctx.ts +69 -0
- package/src/layer-field-rendering.ts +193 -0
- package/src/layer.ts +81 -0
- package/src/observe.ts +361 -0
- package/src/path-scope.ts +66 -0
- package/src/path-security.ts +98 -0
- package/src/patterns/bulk.ts +16 -0
- package/src/patterns/change.ts +12 -0
- package/src/patterns/date-range.ts +12 -0
- package/src/patterns/index.ts +8 -0
- package/src/patterns/pagination.ts +22 -0
- package/src/patterns/progress.ts +13 -0
- package/src/patterns/sorting.ts +14 -0
- package/src/patterns/status.ts +11 -0
- package/src/patterns/timestamps.ts +12 -0
- package/src/permits.ts +12 -0
- package/src/queue.ts +163 -0
- package/src/redaction/index.ts +3 -0
- package/src/redaction/patterns.ts +50 -0
- package/src/redaction/redactor.ts +178 -0
- package/src/resilience.ts +234 -0
- package/src/resource-config.ts +804 -0
- package/src/resource.ts +194 -0
- package/src/result.ts +212 -0
- package/src/run.ts +76 -0
- package/src/runtime-builtins.ts +69 -0
- package/src/schedule-runtime.ts +689 -0
- package/src/schedule.ts +326 -0
- package/src/serialization.ts +265 -0
- package/src/sha256.ts +136 -0
- package/src/signal-diagnostics.ts +633 -0
- package/src/signal-ref.ts +111 -0
- package/src/signal.ts +104 -0
- package/src/store/accessor-protocol.ts +56 -0
- package/src/store/index.ts +4 -0
- package/src/structured-examples.ts +248 -0
- package/src/surface-derivation.ts +91 -0
- package/src/surface-filter.ts +101 -0
- package/src/surface-overlay.ts +694 -0
- package/src/surface-versioning.ts +42 -0
- package/src/topo.ts +835 -0
- package/src/tracing.ts +346 -0
- package/src/trail-id-glob.ts +15 -0
- package/src/trail.ts +1351 -0
- package/src/trails/derive-trail.ts +835 -0
- package/src/trails/index.ts +9 -0
- package/src/trails/ingest.ts +152 -0
- package/src/trails-db.ts +212 -0
- package/src/transport-error-map.ts +163 -0
- package/src/type-utils.ts +87 -0
- package/src/types.ts +300 -0
- package/src/validate-established-topo.ts +73 -0
- package/src/validate-topo.ts +725 -0
- package/src/validation.ts +330 -0
- package/src/version-marker.ts +716 -0
- package/src/version-resolution.ts +308 -0
- package/src/version-runtime.ts +120 -0
- package/src/webhook.ts +461 -0
- package/src/workspace.ts +244 -0
- package/src/zod-wrappers.ts +72 -0
package/README.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# @ontrails/core
|
|
2
|
+
|
|
3
|
+
The foundation. Define trails, compose them into topos, return typed Results, and let the framework derive everything else.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { trail, topo, Result } from '@ontrails/core';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
|
|
11
|
+
const greet = trail('greet', {
|
|
12
|
+
input: z.object({ name: z.string().describe('Who to greet') }),
|
|
13
|
+
output: z.object({ message: z.string() }),
|
|
14
|
+
intent: 'read',
|
|
15
|
+
examples: [
|
|
16
|
+
{ name: 'Hello', input: { name: 'World' }, expected: { message: 'Hello, World!' } },
|
|
17
|
+
],
|
|
18
|
+
implementation: (input) => Result.ok({ message: `Hello, ${input.name}!` }),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const graph = topo('myapp', { greet });
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Trails compose other trails through `composes` and `ctx.compose()`:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
const onboard = trail('entity.onboard', {
|
|
28
|
+
composes: ['entity.add', 'entity.relate'],
|
|
29
|
+
input: z.object({ name: z.string(), type: z.string() }),
|
|
30
|
+
implementation: async (input, ctx) => {
|
|
31
|
+
const added = await ctx.compose('entity.add', input);
|
|
32
|
+
if (added.isErr()) return added;
|
|
33
|
+
return Result.ok({ entity: added.value });
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## API
|
|
39
|
+
|
|
40
|
+
### Trail primitives
|
|
41
|
+
|
|
42
|
+
| Export | What it does |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `trail(id, spec)` | Define a unit of work with typed input and `Result` output; use `composes` for composition |
|
|
45
|
+
| `signal(id, spec)` | Define a server-originated notification with a typed data schema |
|
|
46
|
+
| `resource(id, spec)` | Define an infrastructure dependency with `create`, `dispose`, and optional `mock` |
|
|
47
|
+
| `drainResources(resources, ctx, configValues?)` | Evict and dispose cached resource singletons for surface/test shutdown |
|
|
48
|
+
| `blobRefSchema` / `createBlobRef(...)` | Declare and create binary output references with a shared descriptor contract |
|
|
49
|
+
| `topo(name, ...modules, options?)` | Collect trail modules into a queryable topology with optional `observe:` sinks |
|
|
50
|
+
| `deriveTrail(entity, operation, spec)` | Derive CRUD-shaped trail contracts from a entity on the `@ontrails/core/trails` subpath |
|
|
51
|
+
| `validateTopo(topo)` | Structural validation: compose targets exist, no cycles, examples parse, output schemas present |
|
|
52
|
+
|
|
53
|
+
### Execution
|
|
54
|
+
|
|
55
|
+
| Export | What it does |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `executeTrail(trail, rawInput, options?)` | Centralized execution pipeline: validates input, builds context, composes layers, runs the trail. Never throws -- exceptions become `Result.err(InternalError)`. |
|
|
58
|
+
| `run(topo, id, input, options?)` | Headless trail execution by ID. Looks up the trail in the topo, then delegates to `executeTrail`. Returns `Result.err(NotFoundError)` if the ID is not registered. |
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// executeTrail — surfaces use this directly
|
|
62
|
+
const surfaceResult = await executeTrail(greet, { name: 'Alice' });
|
|
63
|
+
|
|
64
|
+
// run — headless execution by trail ID
|
|
65
|
+
const runResult = await run(graph, 'greet', { name: 'Alice' });
|
|
66
|
+
if (runResult.isOk()) console.log(runResult.value);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Topo accessors
|
|
70
|
+
|
|
71
|
+
Beyond the `trail(id, spec)` builder, `Topo` exposes these accessors:
|
|
72
|
+
|
|
73
|
+
| Accessor | What it returns |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| `topo.ids()` | `string[]` of all registered trail IDs |
|
|
76
|
+
| `topo.count` | Number of registered trails |
|
|
77
|
+
| `topo.get(id)` | The `Trail` with that ID, or `undefined` |
|
|
78
|
+
| `topo.has(id)` | Whether a trail ID is registered |
|
|
79
|
+
| `topo.list()` | All registered trails as an array |
|
|
80
|
+
|
|
81
|
+
### Type utilities
|
|
82
|
+
|
|
83
|
+
| Export | What it does |
|
|
84
|
+
| --- | --- |
|
|
85
|
+
| `TrailInput<T>` | Extract the input type from a `Trail` |
|
|
86
|
+
| `TrailOutput<T>` | Extract the output type from a `Trail` |
|
|
87
|
+
| `TrailResult<T>` | `Result<TrailOutput<T>, Error>` -- the Result type for a trail's output |
|
|
88
|
+
| `inputOf(trail)` | Get the input Zod schema from a trail instance |
|
|
89
|
+
| `outputOf(trail)` | Get the output Zod schema (or `undefined`) from a trail instance |
|
|
90
|
+
|
|
91
|
+
### Execution option types
|
|
92
|
+
|
|
93
|
+
| Type | What it describes |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| `ExecuteTrailOptions` | Options for `executeTrail`: `ctx`, `abortSignal`, `layers`, `createContext` |
|
|
96
|
+
| `RunOptions` | Same shape as `ExecuteTrailOptions`; forwarded by `run` |
|
|
97
|
+
|
|
98
|
+
### Result
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
Result.ok(value); // Success
|
|
102
|
+
Result.err(error); // Failure
|
|
103
|
+
Result.combine(results); // Result<T>[] → Result<T[]>
|
|
104
|
+
Result.fromJson(json); // Parse JSON string into Result
|
|
105
|
+
Result.toJson(value); // Serialize to JSON string as Result
|
|
106
|
+
Result.fromFetch(response); // Convert fetch Response to Result
|
|
107
|
+
|
|
108
|
+
result.isOk(); // Type guard
|
|
109
|
+
result.isErr(); // Type guard
|
|
110
|
+
result.map(fn); // Transform success
|
|
111
|
+
result.flatMap(fn); // Chain Result-returning functions
|
|
112
|
+
result.match({ ok, err }); // Pattern match
|
|
113
|
+
result.unwrapOr(fallback); // Value or fallback
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Error taxonomy
|
|
117
|
+
|
|
118
|
+
The current taxonomy is generated from the `errorClasses` owner registry and category code maps in `@ontrails/core`.
|
|
119
|
+
|
|
120
|
+
<!-- error-taxonomy:start -->
|
|
121
|
+
<!-- GENERATED: run `bun run error-taxonomy:sync`; check with `bun run error-taxonomy:check`. Variant: category. -->
|
|
122
|
+
|
|
123
|
+
| Category | CLI Exit | HTTP | JSON-RPC | Retryable | Fixed Classes |
|
|
124
|
+
| --- | --- | --- | --- | --- | --- |
|
|
125
|
+
| `validation` | 1 | 400 | -32602 | No | `ValidationError`, `AmbiguousError` |
|
|
126
|
+
| `not_found` | 2 | 404 | -32601 | No | `NotFoundError`, `VersionNotSupportedError` |
|
|
127
|
+
| `conflict` | 3 | 409 | -32603 | No | `AlreadyExistsError`, `ConflictError` |
|
|
128
|
+
| `permission` | 4 | 403 | -32600 | No | `PermissionError`, `PermitError` |
|
|
129
|
+
| `timeout` | 5 | 504 | -32603 | Yes | `TimeoutError` |
|
|
130
|
+
| `rate_limit` | 6 | 429 | -32603 | Yes | `RateLimitError` |
|
|
131
|
+
| `network` | 7 | 502 | -32603 | Yes | `NetworkError` |
|
|
132
|
+
| `shift` | 10 | 503 | -32603 | Yes | `WorkspaceShiftError` |
|
|
133
|
+
| `internal` | 8 | 500 | -32603 | No | `AssertionError`, `InternalError`, `DerivationError`, `RecoverableCompletionError` |
|
|
134
|
+
| `auth` | 9 | 401 | -32600 | No | `AuthError` |
|
|
135
|
+
| `cancelled` | 130 | 499 | -32603 | No | `CancelledError` |
|
|
136
|
+
|
|
137
|
+
Dynamic classes:
|
|
138
|
+
|
|
139
|
+
- `RetryExhaustedError` inherits category and surface codes from its wrapped `TrailsError`; retryable is always No.
|
|
140
|
+
<!-- error-taxonomy:end -->
|
|
141
|
+
|
|
142
|
+
Public surfaces share one redacted rendering contract before applying surface codes. Sensitive substrings are removed from non-internal `TrailsError` messages. Internal-category `TrailsError` instances and unknown native errors remain opaque: HTTP, MCP, and library boundaries use `Internal server error`, while CLI uses the transport-neutral `Internal error`. Diagnostics and serialized payloads keep their useful structure while redacting messages, context, and stack strings.
|
|
143
|
+
|
|
144
|
+
The developer returns `Result.err(new NotFoundError(...))`. The framework maps it to the right code on every surface.
|
|
145
|
+
|
|
146
|
+
### Other exports
|
|
147
|
+
|
|
148
|
+
- **Schema derivation** -- `deriveFields(schema)` extracts faithfully
|
|
149
|
+
representable field metadata from Zod for prompts and forms
|
|
150
|
+
- **Validation** -- `validateInput`, `formatZodIssues`, `zodToJsonSchema`
|
|
151
|
+
- **Resilience** -- `retry`, `withTimeout`, `shouldRetry`, `deriveBackoffDelay`
|
|
152
|
+
- **Serialization** -- `serializeError`, `deserializeError`
|
|
153
|
+
- **Branded types** -- `uuid`, `email`, `nonEmptyString`, `positiveInt`
|
|
154
|
+
- **Execution layers** -- low-level pipeline wrappers via `composeLayers`
|
|
155
|
+
- **Guards and collections** -- `isDefined`, `chunk`, `dedupe`, `groupBy`, `sortBy`
|
|
156
|
+
- **Patterns** (`@ontrails/core/patterns`) -- reusable Zod schemas for pagination, bulk ops, timestamps, sorting
|
|
157
|
+
- **Trail factories** (`@ontrails/core/trails`) -- derive CRUD-shaped trail contracts from entities without re-authoring IDs, schemas, examples, or intents
|
|
158
|
+
- **Redaction** (`@ontrails/core/redaction`) -- strip sensitive data before logging
|
|
159
|
+
|
|
160
|
+
### Public helper boundaries
|
|
161
|
+
|
|
162
|
+
The root package also exposes a few low-level contracts that other framework packages build on:
|
|
163
|
+
|
|
164
|
+
- **Intrinsic tracing** -- `TraceRecord`, `TraceSink`, `TraceContext`, and the sink registry helpers are the core-owned execution record shape shared by `@ontrails/observability` and adapters.
|
|
165
|
+
- **Trails DB** -- `deriveTrailsDbPath`, `deriveTrailsStateDir`, `deriveTrailsStateHome`, `deriveTrailsProjectKey`, `deriveTrailsDir`, `ensureSubsystemSchema`, `openReadTrailsDb`, and `openWriteTrailsDb` are the generic database primitive used by framework subsystems.
|
|
166
|
+
- **Surface rendering helpers** -- safe error rendering, layer field rendering, compose-batch validation, late-bound signal references, and Zod default-wrapper stripping are stable root exports for first-party surfaces, store helpers, and tests.
|
|
167
|
+
|
|
168
|
+
See the [API Reference](../../docs/api-reference.md) for the full list.
|
|
169
|
+
|
|
170
|
+
## Migration: topo-store moved to `@ontrails/topography`
|
|
171
|
+
|
|
172
|
+
Per [ADR-0042](../../docs/adr/0042-core-topography-boundary-doctrine.md), the topo-store public API previously exported from `@ontrails/core` now lives in `@ontrails/topography`. Generic `trails-db` helpers (`openReadTrailsDb`, `openWriteTrailsDb`, `ensureSubsystemSchema`, `deriveTrailsDbPath`, `deriveTrailsStateDir`, `deriveTrailsStateHome`, `deriveTrailsProjectKey`, `deriveTrailsDir`) stay in core because tracing and other subsystems share them.
|
|
173
|
+
|
|
174
|
+
Update consumer imports:
|
|
175
|
+
|
|
176
|
+
```diff
|
|
177
|
+
- import { topoStore, createTopoStore, createMockTopoStore, createTopoSnapshot, listTopoSnapshots, pinTopoSnapshot, unpinTopoSnapshot, createStoredTopoSnapshot, getStoredTopoExport, countTopoSnapshots, countPinnedSnapshots, countPrunableSnapshots, pruneUnpinnedSnapshots } from '@ontrails/core';
|
|
178
|
+
+ import { topoStore, createTopoStore, createMockTopoStore, createTopoSnapshot, listTopoSnapshots, pinTopoSnapshot, unpinTopoSnapshot } from '@ontrails/topography';
|
|
179
|
+
+ import { createStoredTopoSnapshot, getStoredTopoExport, countTopoSnapshots, countPinnedSnapshots, countPrunableSnapshots, pruneUnpinnedSnapshots } from '@ontrails/topography/backend-support';
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Types `ReadOnlyTopoStore`, `MockTopoStoreSeed`, `TopoSnapshot`, `TopoStoreRef`, `TopoStoreExportRecord`, `TopoStoreResourceRecord`, `TopoStoreTrailRecord`, `TopoStoreTrailDetailRecord`, `CreateTopoSnapshotInput`, and `ListTopoSnapshotsOptions` move to `@ontrails/topography`. `StoredTopoExport` moves to `@ontrails/topography/backend-support`.
|
|
183
|
+
|
|
184
|
+
## Installation
|
|
185
|
+
|
|
186
|
+
These commands target stable `0.2.0`. Run them after that version is published to npm.
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
bun add --exact @ontrails/core@0.2.0 zod
|
|
190
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ontrails/core",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/outfitter-dev/trails.git",
|
|
7
|
+
"directory": "packages/core"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"src/**/*.ts",
|
|
11
|
+
"!src/**/__tests__/**",
|
|
12
|
+
"!src/**/*.test.ts",
|
|
13
|
+
"!src/**/*.test-d.ts",
|
|
14
|
+
"README.md",
|
|
15
|
+
"CHANGELOG.md"
|
|
16
|
+
],
|
|
17
|
+
"type": "module",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": "./src/index.ts",
|
|
20
|
+
"./patterns": "./src/patterns/index.ts",
|
|
21
|
+
"./redaction": "./src/redaction/index.ts",
|
|
22
|
+
"./store": "./src/store/index.ts",
|
|
23
|
+
"./trails": "./src/trails/index.ts",
|
|
24
|
+
"./package.json": "./package.json"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc -b",
|
|
28
|
+
"test": "bun test",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"lint": "oxlint ./src",
|
|
31
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"zod": "^4.3.5"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ActivationSourceKind,
|
|
3
|
+
ActivationSourceMeta,
|
|
4
|
+
} from './activation-source.js';
|
|
5
|
+
|
|
6
|
+
export const ACTIVATION_PROVENANCE_KEY =
|
|
7
|
+
'__trails_activation_provenance' as const;
|
|
8
|
+
|
|
9
|
+
export interface ActivationProvenanceSource {
|
|
10
|
+
readonly cron?: string | undefined;
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly kind: ActivationSourceKind;
|
|
13
|
+
readonly meta?: ActivationSourceMeta | undefined;
|
|
14
|
+
readonly producerTrailId?: string | undefined;
|
|
15
|
+
readonly queue?: string | undefined;
|
|
16
|
+
readonly timezone?: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ActivationProvenance {
|
|
20
|
+
readonly fireId: string;
|
|
21
|
+
readonly parentFireId?: string | undefined;
|
|
22
|
+
readonly rootFireId: string;
|
|
23
|
+
readonly source: ActivationProvenanceSource;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ActivationProvenanceCarrier {
|
|
27
|
+
readonly activation?: ActivationProvenance | undefined;
|
|
28
|
+
readonly extensions?: Readonly<Record<string, unknown>> | undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const isObjectRecord = (value: unknown): value is Record<string, unknown> =>
|
|
32
|
+
typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
33
|
+
|
|
34
|
+
const optionalString = (value: unknown): boolean =>
|
|
35
|
+
value === undefined || typeof value === 'string';
|
|
36
|
+
|
|
37
|
+
const isActivationProvenanceSource = (
|
|
38
|
+
value: unknown
|
|
39
|
+
): value is ActivationProvenanceSource =>
|
|
40
|
+
isObjectRecord(value) &&
|
|
41
|
+
typeof value['id'] === 'string' &&
|
|
42
|
+
typeof value['kind'] === 'string' &&
|
|
43
|
+
optionalString(value['cron']) &&
|
|
44
|
+
optionalString(value['producerTrailId']) &&
|
|
45
|
+
optionalString(value['queue']) &&
|
|
46
|
+
optionalString(value['timezone']) &&
|
|
47
|
+
(value['meta'] === undefined || isObjectRecord(value['meta']));
|
|
48
|
+
|
|
49
|
+
const isActivationProvenance = (
|
|
50
|
+
value: unknown
|
|
51
|
+
): value is ActivationProvenance =>
|
|
52
|
+
isObjectRecord(value) &&
|
|
53
|
+
typeof value['fireId'] === 'string' &&
|
|
54
|
+
optionalString(value['parentFireId']) &&
|
|
55
|
+
typeof value['rootFireId'] === 'string' &&
|
|
56
|
+
isActivationProvenanceSource(value['source']);
|
|
57
|
+
|
|
58
|
+
export const getActivationProvenance = (
|
|
59
|
+
ctx: ActivationProvenanceCarrier | undefined
|
|
60
|
+
): ActivationProvenance | undefined => {
|
|
61
|
+
if (isActivationProvenance(ctx?.activation)) {
|
|
62
|
+
return ctx.activation;
|
|
63
|
+
}
|
|
64
|
+
const fromExtensions = ctx?.extensions?.[ACTIVATION_PROVENANCE_KEY];
|
|
65
|
+
return isActivationProvenance(fromExtensions) ? fromExtensions : undefined;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const withActivationProvenance = <
|
|
69
|
+
TCtx extends {
|
|
70
|
+
readonly extensions?: Readonly<Record<string, unknown>> | undefined;
|
|
71
|
+
},
|
|
72
|
+
>(
|
|
73
|
+
ctx: TCtx,
|
|
74
|
+
activation: ActivationProvenance
|
|
75
|
+
): TCtx & { readonly activation: ActivationProvenance } => ({
|
|
76
|
+
...ctx,
|
|
77
|
+
activation,
|
|
78
|
+
extensions: {
|
|
79
|
+
...ctx.extensions,
|
|
80
|
+
[ACTIVATION_PROVENANCE_KEY]: activation,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export const buildActivationProvenanceTraceAttrs = (
|
|
85
|
+
activation: ActivationProvenance | undefined
|
|
86
|
+
): Readonly<Record<string, unknown>> => {
|
|
87
|
+
if (activation === undefined) {
|
|
88
|
+
return {};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const attrs: Record<string, unknown> = {
|
|
92
|
+
'trails.activation.fire_id': activation.fireId,
|
|
93
|
+
'trails.activation.root_fire_id': activation.rootFireId,
|
|
94
|
+
'trails.activation.source.id': activation.source.id,
|
|
95
|
+
'trails.activation.source.kind': activation.source.kind,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
if (activation.parentFireId !== undefined) {
|
|
99
|
+
attrs['trails.activation.parent_fire_id'] = activation.parentFireId;
|
|
100
|
+
}
|
|
101
|
+
if (activation.source.producerTrailId !== undefined) {
|
|
102
|
+
attrs['trails.activation.source.producer_trail.id'] =
|
|
103
|
+
activation.source.producerTrailId;
|
|
104
|
+
}
|
|
105
|
+
if (activation.source.queue !== undefined) {
|
|
106
|
+
attrs['trails.activation.source.queue'] = activation.source.queue;
|
|
107
|
+
}
|
|
108
|
+
if (activation.source.cron !== undefined) {
|
|
109
|
+
attrs['trails.activation.source.cron'] = activation.source.cron;
|
|
110
|
+
}
|
|
111
|
+
if (activation.source.timezone !== undefined) {
|
|
112
|
+
attrs['trails.activation.source.timezone'] = activation.source.timezone;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return attrs;
|
|
116
|
+
};
|