@unlaxer/tramli-plugins 3.3.0 → 3.5.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/dist/cjs/eventstore/replay-service.d.ts +16 -3
- package/dist/cjs/eventstore/replay-service.js +16 -3
- package/dist/cjs/lint/policy-lint-plugin.d.ts +3 -2
- package/dist/cjs/lint/policy-lint-plugin.js +4 -1
- package/dist/cjs/observability/observability-plugin.d.ts +3 -1
- package/dist/cjs/observability/observability-plugin.js +19 -5
- package/dist/esm/eventstore/replay-service.d.ts +16 -3
- package/dist/esm/eventstore/replay-service.js +16 -3
- package/dist/esm/lint/policy-lint-plugin.d.ts +3 -2
- package/dist/esm/lint/policy-lint-plugin.js +4 -1
- package/dist/esm/observability/observability-plugin.d.ts +3 -1
- package/dist/esm/observability/observability-plugin.js +19 -5
- package/package.json +1 -1
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import type { VersionedTransitionEvent, ProjectionReducer } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Replay service —
|
|
4
|
-
*
|
|
3
|
+
* Replay service — reconstructs flow state at any version.
|
|
4
|
+
*
|
|
5
|
+
* Assumes each TRANSITION event stores a full snapshot of the state.
|
|
6
|
+
* Returns the latest matching state at or before the requested version.
|
|
7
|
+
*
|
|
8
|
+
* If the event log is later changed to store diffs instead of full snapshots,
|
|
9
|
+
* use {@link ProjectionReplayService} with a fold/reducer instead.
|
|
5
10
|
*/
|
|
6
11
|
export declare class ReplayService {
|
|
7
12
|
stateAtVersion(events: readonly VersionedTransitionEvent[], flowId: string, targetVersion: number): string | null;
|
|
8
13
|
}
|
|
9
14
|
/**
|
|
10
|
-
* Projection replay service —
|
|
15
|
+
* Projection replay service — fold/reducer model for custom aggregations.
|
|
16
|
+
*
|
|
17
|
+
* Unlike {@link ReplayService} which assumes full snapshots,
|
|
18
|
+
* this service supports both full-snapshot and diff-based event logs.
|
|
19
|
+
* `reducer.initialState()` returns the empty starting state,
|
|
20
|
+
* `reducer.apply(state, event)` accumulates each event.
|
|
21
|
+
*
|
|
22
|
+
* Use for custom aggregations (transition count, cumulative metrics)
|
|
23
|
+
* or when the event log stores diffs rather than full snapshots.
|
|
11
24
|
*/
|
|
12
25
|
export declare class ProjectionReplayService {
|
|
13
26
|
stateAtVersion<T>(events: readonly VersionedTransitionEvent[], flowId: string, targetVersion: number, reducer: ProjectionReducer<T>): T;
|
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ProjectionReplayService = exports.ReplayService = void 0;
|
|
4
4
|
/**
|
|
5
|
-
* Replay service —
|
|
6
|
-
*
|
|
5
|
+
* Replay service — reconstructs flow state at any version.
|
|
6
|
+
*
|
|
7
|
+
* Assumes each TRANSITION event stores a full snapshot of the state.
|
|
8
|
+
* Returns the latest matching state at or before the requested version.
|
|
9
|
+
*
|
|
10
|
+
* If the event log is later changed to store diffs instead of full snapshots,
|
|
11
|
+
* use {@link ProjectionReplayService} with a fold/reducer instead.
|
|
7
12
|
*/
|
|
8
13
|
class ReplayService {
|
|
9
14
|
stateAtVersion(events, flowId, targetVersion) {
|
|
@@ -17,7 +22,15 @@ class ReplayService {
|
|
|
17
22
|
}
|
|
18
23
|
exports.ReplayService = ReplayService;
|
|
19
24
|
/**
|
|
20
|
-
* Projection replay service —
|
|
25
|
+
* Projection replay service — fold/reducer model for custom aggregations.
|
|
26
|
+
*
|
|
27
|
+
* Unlike {@link ReplayService} which assumes full snapshots,
|
|
28
|
+
* this service supports both full-snapshot and diff-based event logs.
|
|
29
|
+
* `reducer.initialState()` returns the empty starting state,
|
|
30
|
+
* `reducer.apply(state, event)` accumulates each event.
|
|
31
|
+
*
|
|
32
|
+
* Use for custom aggregations (transition count, cumulative metrics)
|
|
33
|
+
* or when the event log stores diffs rather than full snapshots.
|
|
21
34
|
*/
|
|
22
35
|
class ProjectionReplayService {
|
|
23
36
|
stateAtVersion(events, flowId, targetVersion, reducer) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FlowDefinition } from '@unlaxer/tramli';
|
|
2
|
-
import type { AnalysisPlugin, PluginDescriptor
|
|
2
|
+
import type { AnalysisPlugin, PluginDescriptor } from '../api/types.js';
|
|
3
|
+
import { PluginReport } from '../api/types.js';
|
|
3
4
|
import type { FlowPolicy } from './types.js';
|
|
4
5
|
export declare class PolicyLintPlugin<S extends string> implements AnalysisPlugin<S> {
|
|
5
6
|
private readonly policies;
|
|
@@ -7,5 +8,5 @@ export declare class PolicyLintPlugin<S extends string> implements AnalysisPlugi
|
|
|
7
8
|
static defaults<S extends string>(): PolicyLintPlugin<S>;
|
|
8
9
|
descriptor(): PluginDescriptor;
|
|
9
10
|
kind(): "ANALYSIS";
|
|
10
|
-
analyze(definition: FlowDefinition<S>, report
|
|
11
|
+
analyze(definition: FlowDefinition<S>, report?: PluginReport): PluginReport;
|
|
11
12
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PolicyLintPlugin = void 0;
|
|
4
|
+
const types_js_1 = require("../api/types.js");
|
|
4
5
|
const default_flow_policies_js_1 = require("./default-flow-policies.js");
|
|
5
6
|
class PolicyLintPlugin {
|
|
6
7
|
policies;
|
|
@@ -19,9 +20,11 @@ class PolicyLintPlugin {
|
|
|
19
20
|
}
|
|
20
21
|
kind() { return 'ANALYSIS'; }
|
|
21
22
|
analyze(definition, report) {
|
|
23
|
+
const r = report ?? new types_js_1.PluginReport();
|
|
22
24
|
for (const policy of this.policies) {
|
|
23
|
-
policy(definition,
|
|
25
|
+
policy(definition, r);
|
|
24
26
|
}
|
|
27
|
+
return r;
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
exports.PolicyLintPlugin = PolicyLintPlugin;
|
|
@@ -21,5 +21,7 @@ export declare class ObservabilityEnginePlugin implements EnginePlugin {
|
|
|
21
21
|
constructor(sink: TelemetrySink);
|
|
22
22
|
descriptor(): PluginDescriptor;
|
|
23
23
|
kind(): "ENGINE";
|
|
24
|
-
install(engine: FlowEngine
|
|
24
|
+
install(engine: FlowEngine, options?: {
|
|
25
|
+
append?: boolean;
|
|
26
|
+
}): void;
|
|
25
27
|
}
|
|
@@ -16,18 +16,32 @@ class ObservabilityEnginePlugin {
|
|
|
16
16
|
return { id: 'observability', displayName: 'Observability', description: 'Telemetry via engine logger hooks' };
|
|
17
17
|
}
|
|
18
18
|
kind() { return 'ENGINE'; }
|
|
19
|
-
install(engine) {
|
|
19
|
+
install(engine, options) {
|
|
20
|
+
const append = options?.append ?? false;
|
|
21
|
+
const prevTransition = append ? engine.getTransitionLogger() : undefined;
|
|
22
|
+
const prevError = append ? engine.getErrorLogger() : undefined;
|
|
23
|
+
const prevGuard = append ? engine.getGuardLogger() : undefined;
|
|
20
24
|
engine.setTransitionLogger(entry => {
|
|
25
|
+
prevTransition?.(entry);
|
|
21
26
|
this.sink.emit({
|
|
22
|
-
type: 'transition', flowId: entry.flowId, flowName:
|
|
23
|
-
data: { from: entry.from, to: entry.to, trigger: entry.trigger },
|
|
27
|
+
type: 'transition', flowId: entry.flowId, flowName: entry.flowName,
|
|
28
|
+
data: { from: entry.from, to: entry.to, trigger: entry.trigger, durationMicros: entry.durationMicros },
|
|
24
29
|
timestamp: new Date(),
|
|
25
30
|
});
|
|
26
31
|
});
|
|
27
32
|
engine.setErrorLogger(entry => {
|
|
33
|
+
prevError?.(entry);
|
|
28
34
|
this.sink.emit({
|
|
29
|
-
type: 'error', flowId: entry.flowId, flowName:
|
|
30
|
-
data: { from: entry.from, to: entry.to, trigger: entry.trigger, cause: entry.cause?.message },
|
|
35
|
+
type: 'error', flowId: entry.flowId, flowName: entry.flowName,
|
|
36
|
+
data: { from: entry.from, to: entry.to, trigger: entry.trigger, cause: entry.cause?.message, durationMicros: entry.durationMicros },
|
|
37
|
+
timestamp: new Date(),
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
engine.setGuardLogger((entry) => {
|
|
41
|
+
prevGuard?.(entry);
|
|
42
|
+
this.sink.emit({
|
|
43
|
+
type: 'guard', flowId: entry.flowId, flowName: entry.flowName,
|
|
44
|
+
data: { state: entry.state, guardName: entry.guardName, result: entry.result, reason: entry.reason, durationMicros: entry.durationMicros },
|
|
31
45
|
timestamp: new Date(),
|
|
32
46
|
});
|
|
33
47
|
});
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import type { VersionedTransitionEvent, ProjectionReducer } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Replay service —
|
|
4
|
-
*
|
|
3
|
+
* Replay service — reconstructs flow state at any version.
|
|
4
|
+
*
|
|
5
|
+
* Assumes each TRANSITION event stores a full snapshot of the state.
|
|
6
|
+
* Returns the latest matching state at or before the requested version.
|
|
7
|
+
*
|
|
8
|
+
* If the event log is later changed to store diffs instead of full snapshots,
|
|
9
|
+
* use {@link ProjectionReplayService} with a fold/reducer instead.
|
|
5
10
|
*/
|
|
6
11
|
export declare class ReplayService {
|
|
7
12
|
stateAtVersion(events: readonly VersionedTransitionEvent[], flowId: string, targetVersion: number): string | null;
|
|
8
13
|
}
|
|
9
14
|
/**
|
|
10
|
-
* Projection replay service —
|
|
15
|
+
* Projection replay service — fold/reducer model for custom aggregations.
|
|
16
|
+
*
|
|
17
|
+
* Unlike {@link ReplayService} which assumes full snapshots,
|
|
18
|
+
* this service supports both full-snapshot and diff-based event logs.
|
|
19
|
+
* `reducer.initialState()` returns the empty starting state,
|
|
20
|
+
* `reducer.apply(state, event)` accumulates each event.
|
|
21
|
+
*
|
|
22
|
+
* Use for custom aggregations (transition count, cumulative metrics)
|
|
23
|
+
* or when the event log stores diffs rather than full snapshots.
|
|
11
24
|
*/
|
|
12
25
|
export declare class ProjectionReplayService {
|
|
13
26
|
stateAtVersion<T>(events: readonly VersionedTransitionEvent[], flowId: string, targetVersion: number, reducer: ProjectionReducer<T>): T;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Replay service —
|
|
3
|
-
*
|
|
2
|
+
* Replay service — reconstructs flow state at any version.
|
|
3
|
+
*
|
|
4
|
+
* Assumes each TRANSITION event stores a full snapshot of the state.
|
|
5
|
+
* Returns the latest matching state at or before the requested version.
|
|
6
|
+
*
|
|
7
|
+
* If the event log is later changed to store diffs instead of full snapshots,
|
|
8
|
+
* use {@link ProjectionReplayService} with a fold/reducer instead.
|
|
4
9
|
*/
|
|
5
10
|
export class ReplayService {
|
|
6
11
|
stateAtVersion(events, flowId, targetVersion) {
|
|
@@ -13,7 +18,15 @@ export class ReplayService {
|
|
|
13
18
|
}
|
|
14
19
|
}
|
|
15
20
|
/**
|
|
16
|
-
* Projection replay service —
|
|
21
|
+
* Projection replay service — fold/reducer model for custom aggregations.
|
|
22
|
+
*
|
|
23
|
+
* Unlike {@link ReplayService} which assumes full snapshots,
|
|
24
|
+
* this service supports both full-snapshot and diff-based event logs.
|
|
25
|
+
* `reducer.initialState()` returns the empty starting state,
|
|
26
|
+
* `reducer.apply(state, event)` accumulates each event.
|
|
27
|
+
*
|
|
28
|
+
* Use for custom aggregations (transition count, cumulative metrics)
|
|
29
|
+
* or when the event log stores diffs rather than full snapshots.
|
|
17
30
|
*/
|
|
18
31
|
export class ProjectionReplayService {
|
|
19
32
|
stateAtVersion(events, flowId, targetVersion, reducer) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FlowDefinition } from '@unlaxer/tramli';
|
|
2
|
-
import type { AnalysisPlugin, PluginDescriptor
|
|
2
|
+
import type { AnalysisPlugin, PluginDescriptor } from '../api/types.js';
|
|
3
|
+
import { PluginReport } from '../api/types.js';
|
|
3
4
|
import type { FlowPolicy } from './types.js';
|
|
4
5
|
export declare class PolicyLintPlugin<S extends string> implements AnalysisPlugin<S> {
|
|
5
6
|
private readonly policies;
|
|
@@ -7,5 +8,5 @@ export declare class PolicyLintPlugin<S extends string> implements AnalysisPlugi
|
|
|
7
8
|
static defaults<S extends string>(): PolicyLintPlugin<S>;
|
|
8
9
|
descriptor(): PluginDescriptor;
|
|
9
10
|
kind(): "ANALYSIS";
|
|
10
|
-
analyze(definition: FlowDefinition<S>, report
|
|
11
|
+
analyze(definition: FlowDefinition<S>, report?: PluginReport): PluginReport;
|
|
11
12
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PluginReport } from '../api/types.js';
|
|
1
2
|
import { allDefaultPolicies } from './default-flow-policies.js';
|
|
2
3
|
export class PolicyLintPlugin {
|
|
3
4
|
policies;
|
|
@@ -16,8 +17,10 @@ export class PolicyLintPlugin {
|
|
|
16
17
|
}
|
|
17
18
|
kind() { return 'ANALYSIS'; }
|
|
18
19
|
analyze(definition, report) {
|
|
20
|
+
const r = report ?? new PluginReport();
|
|
19
21
|
for (const policy of this.policies) {
|
|
20
|
-
policy(definition,
|
|
22
|
+
policy(definition, r);
|
|
21
23
|
}
|
|
24
|
+
return r;
|
|
22
25
|
}
|
|
23
26
|
}
|
|
@@ -21,5 +21,7 @@ export declare class ObservabilityEnginePlugin implements EnginePlugin {
|
|
|
21
21
|
constructor(sink: TelemetrySink);
|
|
22
22
|
descriptor(): PluginDescriptor;
|
|
23
23
|
kind(): "ENGINE";
|
|
24
|
-
install(engine: FlowEngine
|
|
24
|
+
install(engine: FlowEngine, options?: {
|
|
25
|
+
append?: boolean;
|
|
26
|
+
}): void;
|
|
25
27
|
}
|
|
@@ -12,18 +12,32 @@ export class ObservabilityEnginePlugin {
|
|
|
12
12
|
return { id: 'observability', displayName: 'Observability', description: 'Telemetry via engine logger hooks' };
|
|
13
13
|
}
|
|
14
14
|
kind() { return 'ENGINE'; }
|
|
15
|
-
install(engine) {
|
|
15
|
+
install(engine, options) {
|
|
16
|
+
const append = options?.append ?? false;
|
|
17
|
+
const prevTransition = append ? engine.getTransitionLogger() : undefined;
|
|
18
|
+
const prevError = append ? engine.getErrorLogger() : undefined;
|
|
19
|
+
const prevGuard = append ? engine.getGuardLogger() : undefined;
|
|
16
20
|
engine.setTransitionLogger(entry => {
|
|
21
|
+
prevTransition?.(entry);
|
|
17
22
|
this.sink.emit({
|
|
18
|
-
type: 'transition', flowId: entry.flowId, flowName:
|
|
19
|
-
data: { from: entry.from, to: entry.to, trigger: entry.trigger },
|
|
23
|
+
type: 'transition', flowId: entry.flowId, flowName: entry.flowName,
|
|
24
|
+
data: { from: entry.from, to: entry.to, trigger: entry.trigger, durationMicros: entry.durationMicros },
|
|
20
25
|
timestamp: new Date(),
|
|
21
26
|
});
|
|
22
27
|
});
|
|
23
28
|
engine.setErrorLogger(entry => {
|
|
29
|
+
prevError?.(entry);
|
|
24
30
|
this.sink.emit({
|
|
25
|
-
type: 'error', flowId: entry.flowId, flowName:
|
|
26
|
-
data: { from: entry.from, to: entry.to, trigger: entry.trigger, cause: entry.cause?.message },
|
|
31
|
+
type: 'error', flowId: entry.flowId, flowName: entry.flowName,
|
|
32
|
+
data: { from: entry.from, to: entry.to, trigger: entry.trigger, cause: entry.cause?.message, durationMicros: entry.durationMicros },
|
|
33
|
+
timestamp: new Date(),
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
engine.setGuardLogger((entry) => {
|
|
37
|
+
prevGuard?.(entry);
|
|
38
|
+
this.sink.emit({
|
|
39
|
+
type: 'guard', flowId: entry.flowId, flowName: entry.flowName,
|
|
40
|
+
data: { state: entry.state, guardName: entry.guardName, result: entry.result, reason: entry.reason, durationMicros: entry.durationMicros },
|
|
27
41
|
timestamp: new Date(),
|
|
28
42
|
});
|
|
29
43
|
});
|
package/package.json
CHANGED