@glubean/sdk 0.7.0 → 0.8.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.
Files changed (58) hide show
  1. package/dist/contract-http/adapter.d.ts.map +1 -1
  2. package/dist/contract-http/adapter.js +9 -0
  3. package/dist/contract-http/adapter.js.map +1 -1
  4. package/dist/data-path.d.ts.map +1 -1
  5. package/dist/data-path.js +10 -2
  6. package/dist/data-path.js.map +1 -1
  7. package/dist/load/artifact.d.ts +376 -0
  8. package/dist/load/artifact.d.ts.map +1 -0
  9. package/dist/load/artifact.js +14 -0
  10. package/dist/load/artifact.js.map +1 -0
  11. package/dist/load/builder.d.ts +80 -0
  12. package/dist/load/builder.d.ts.map +1 -0
  13. package/dist/load/builder.js +262 -0
  14. package/dist/load/builder.js.map +1 -0
  15. package/dist/load/context.d.ts +81 -0
  16. package/dist/load/context.d.ts.map +1 -0
  17. package/dist/load/context.js +2 -0
  18. package/dist/load/context.js.map +1 -0
  19. package/dist/load/duration.d.ts +9 -0
  20. package/dist/load/duration.d.ts.map +1 -0
  21. package/dist/load/duration.js +22 -0
  22. package/dist/load/duration.js.map +1 -0
  23. package/dist/load/events.d.ts +132 -0
  24. package/dist/load/events.d.ts.map +1 -0
  25. package/dist/load/events.js +2 -0
  26. package/dist/load/events.js.map +1 -0
  27. package/dist/load/feeder.d.ts +118 -0
  28. package/dist/load/feeder.d.ts.map +1 -0
  29. package/dist/load/feeder.js +170 -0
  30. package/dist/load/feeder.js.map +1 -0
  31. package/dist/load/index.d.ts +32 -0
  32. package/dist/load/index.d.ts.map +1 -0
  33. package/dist/load/index.js +7 -0
  34. package/dist/load/index.js.map +1 -0
  35. package/dist/load/progress.d.ts +56 -0
  36. package/dist/load/progress.d.ts.map +1 -0
  37. package/dist/load/progress.js +2 -0
  38. package/dist/load/progress.js.map +1 -0
  39. package/dist/load/projection.d.ts +36 -0
  40. package/dist/load/projection.d.ts.map +1 -0
  41. package/dist/load/projection.js +47 -0
  42. package/dist/load/projection.js.map +1 -0
  43. package/dist/load/runner.d.ts +201 -0
  44. package/dist/load/runner.d.ts.map +1 -0
  45. package/dist/load/runner.js +78 -0
  46. package/dist/load/runner.js.map +1 -0
  47. package/dist/load/scenario.d.ts +130 -0
  48. package/dist/load/scenario.d.ts.map +1 -0
  49. package/dist/load/scenario.js +9 -0
  50. package/dist/load/scenario.js.map +1 -0
  51. package/dist/load/step.d.ts +42 -0
  52. package/dist/load/step.d.ts.map +1 -0
  53. package/dist/load/step.js +2 -0
  54. package/dist/load/step.js.map +1 -0
  55. package/dist/types.d.ts +16 -0
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/types.js.map +1 -1
  58. package/package.json +5 -1
@@ -0,0 +1,118 @@
1
+ /** Built-in allocation strategies. */
2
+ export type FeederStrategy = "uniquePerVu" | "uniquePerIteration" | "roundRobin" | "random" | "weightedRandom" | "partitionByVu";
3
+ /** What to do when a feeder runs out of rows. */
4
+ export type ExhaustedPolicy = "fail" | "recycle" | "skip" | "wait";
5
+ /** Common options for an allocation strategy. */
6
+ export interface FeederStrategyOptions {
7
+ exhausted?: ExhaustedPolicy;
8
+ }
9
+ /** Options for `weightedRandom` — `weight` names the numeric weight field. */
10
+ export interface WeightedRandomOptions extends FeederStrategyOptions {
11
+ weight: string;
12
+ }
13
+ /** Options for constructing a feeder source. */
14
+ export interface FeederSourceOptions {
15
+ /** Row field used as the report / uniqueness key. */
16
+ key?: string;
17
+ }
18
+ /** Context the load runtime provides when drawing a row. */
19
+ export interface FeederDrawContext {
20
+ /** 0-based producer slot index. */
21
+ producerSlot: number;
22
+ /** Total number of producer slots (concurrency) — used by `partitionByVu`. */
23
+ producerCount: number;
24
+ /** 0-based iteration index within this producer slot. */
25
+ slotIteration: number;
26
+ /** 0-based global iteration index across all slots. */
27
+ globalIteration: number;
28
+ /**
29
+ * 0-based count of how many times THIS feeder has already been drawn across all slots —
30
+ * the run-global DRAW index. Equals `globalIteration` for a single scenario (a feeder is
31
+ * drawn every iteration); in a traffic mix it advances only on iterations that draw this
32
+ * feeder, so a per-entry (or partially-overridden shared) feeder consumes its rows
33
+ * contiguously. Built-in `uniquePerIteration` / `roundRobin` index by it. Optional: a
34
+ * caller that omits it falls back to `globalIteration` (single-scenario parity).
35
+ */
36
+ drawIndex?: number;
37
+ /** 0-based count of how many times THIS feeder has already been drawn BY THIS producer
38
+ * slot — the per-slot DRAW index (the slot-scoped analogue of `drawIndex`). Built-in
39
+ * `partitionByVu` indexes by it; omitting it falls back to `slotIteration`. */
40
+ slotDrawIndex?: number;
41
+ }
42
+ /** Result of a feeder draw. */
43
+ export type FeederDraw<T> = {
44
+ outcome: "value";
45
+ value: T;
46
+ key?: string;
47
+ } | {
48
+ outcome: "exhausted";
49
+ } | {
50
+ outcome: "skip";
51
+ } | {
52
+ outcome: "wait";
53
+ };
54
+ /**
55
+ * A resolved feeder binding, ready for the load runtime to draw rows from.
56
+ */
57
+ export interface FeederBinding<T = unknown> {
58
+ readonly __glubean_type: "load-feeder";
59
+ readonly strategy: FeederStrategy;
60
+ readonly exhausted: ExhaustedPolicy;
61
+ /** Row field used as the report / uniqueness key, if configured. */
62
+ readonly key?: string;
63
+ /** Row field carrying the weight (`weightedRandom` only). */
64
+ readonly weight?: string;
65
+ /** Number of rows backing this feeder (single-node, in-memory). */
66
+ readonly size: number;
67
+ /** Draw a row for the given allocation context. */
68
+ allocate(ctx: FeederDrawContext): FeederDraw<T>;
69
+ }
70
+ /** A feeder data source; call a strategy method to get a `FeederBinding`. */
71
+ export interface FeederSource<T = unknown> {
72
+ readonly rows: readonly T[];
73
+ /** One row per producer slot, fixed for that slot's lifetime. Default: fail. */
74
+ uniquePerVu(opts?: FeederStrategyOptions): FeederBinding<T>;
75
+ /** A fresh, never-reused row per iteration. Default: fail. */
76
+ uniquePerIteration(opts?: FeederStrategyOptions): FeederBinding<T>;
77
+ /** Cycle through rows in order. Default: recycle. */
78
+ roundRobin(opts?: FeederStrategyOptions): FeederBinding<T>;
79
+ /** Uniformly random row each draw. Default: recycle. */
80
+ random(opts?: FeederStrategyOptions): FeederBinding<T>;
81
+ /** Weighted-random row by a numeric field. Default: recycle. */
82
+ weightedRandom(opts: WeightedRandomOptions): FeederBinding<T>;
83
+ /** Shard rows across producer slots (avoids contention). Default: fail. */
84
+ partitionByVu(opts?: FeederStrategyOptions): FeederBinding<T>;
85
+ }
86
+ /**
87
+ * Feeder data-source factories. `fromArray` is synchronous; `fromJson` /
88
+ * `fromCsv` read a file and must be awaited.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * const users = feeder.fromArray([{ userId: "u1" }, { userId: "u2" }], { key: "userId" });
93
+ * const products = await feeder.fromJson("./data/products.json", { key: "sku" });
94
+ * loadRunner("checkout", {
95
+ * scenario,
96
+ * concurrency: 300,
97
+ * feeders: {
98
+ * user: users.uniquePerVu({ exhausted: "fail" }),
99
+ * product: products.weightedRandom({ weight: "trafficWeight" }),
100
+ * },
101
+ * input: ({ feed }) => ({ user: feed.user, product: feed.product }),
102
+ * });
103
+ * ```
104
+ */
105
+ export declare const feeder: {
106
+ /** In-memory rows. */
107
+ fromArray<T extends object>(rows: readonly T[], opts?: FeederSourceOptions): FeederSource<T>;
108
+ /** Load rows from a JSON file (array, or `pick` a nested array). Await it. */
109
+ fromJson<T extends object = Record<string, unknown>>(path: string, opts?: FeederSourceOptions & {
110
+ pick?: string;
111
+ }): Promise<FeederSource<T>>;
112
+ /** Load rows from a CSV/TSV file. Await it. */
113
+ fromCsv<T extends object = Record<string, string>>(path: string, opts?: FeederSourceOptions & {
114
+ separator?: string;
115
+ headers?: boolean;
116
+ }): Promise<FeederSource<T>>;
117
+ };
118
+ //# sourceMappingURL=feeder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feeder.d.ts","sourceRoot":"","sources":["../../src/load/feeder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Feeder: data source + allocation strategy + scope + exhaustion policy.
3
+ *
4
+ * A feeder draws rows for a producer slot / iteration during load execution.
5
+ * It is NOT inventory expansion (that's `loadRunner.each()`); a feeder does not
6
+ * generate runnables, it allocates data at run time.
7
+ *
8
+ * M1-d is the in-memory implementation: `feeder.fromArray()` is the synchronous
9
+ * core; `feeder.fromJson()` / `feeder.fromCsv()` reuse the SDK data loaders.
10
+ * Allocation is single-node only — `uniquePerVu` / `uniquePerIteration` /
11
+ * `partitionByVu` guarantee uniqueness on one node; a distributed engine needs
12
+ * its own coordination layer (the artifact records `feederGuarantee`).
13
+ */
14
+ import { fromCsv as loadCsv, fromJson as loadJson } from "../data.js";
15
+ // =============================================================================
16
+ // Allocation
17
+ // =============================================================================
18
+ function toValueDraw(row, key) {
19
+ if (key === undefined)
20
+ return { outcome: "value", value: row };
21
+ return { outcome: "value", value: row, key: String(row[key]) };
22
+ }
23
+ function missDraw(policy) {
24
+ switch (policy) {
25
+ case "skip":
26
+ return { outcome: "skip" };
27
+ case "wait":
28
+ return { outcome: "wait" };
29
+ // `recycle` can't recycle an empty/over-range set with no rows → behaves as fail
30
+ default:
31
+ return { outcome: "exhausted" };
32
+ }
33
+ }
34
+ function drawIndexed(rows, rawIndex, policy, key) {
35
+ if (rows.length === 0)
36
+ return missDraw(policy);
37
+ if (rawIndex >= 0 && rawIndex < rows.length)
38
+ return toValueDraw(rows[rawIndex], key);
39
+ if (policy === "recycle") {
40
+ const wrapped = ((rawIndex % rows.length) + rows.length) % rows.length;
41
+ return toValueDraw(rows[wrapped], key);
42
+ }
43
+ return missDraw(policy);
44
+ }
45
+ function pickWeighted(rows, weightField) {
46
+ let total = 0;
47
+ const weights = rows.map((row) => {
48
+ const raw = Number(row[weightField]);
49
+ const w = Number.isFinite(raw) && raw > 0 ? raw : 0;
50
+ total += w;
51
+ return w;
52
+ });
53
+ if (total <= 0)
54
+ return undefined;
55
+ let r = Math.random() * total;
56
+ for (let i = 0; i < rows.length; i++) {
57
+ r -= weights[i];
58
+ if (r < 0)
59
+ return rows[i];
60
+ }
61
+ return rows[rows.length - 1];
62
+ }
63
+ function makeBinding(rows, strategy, exhausted, key, weight) {
64
+ const allocate = (ctx) => {
65
+ switch (strategy) {
66
+ case "uniquePerVu":
67
+ return drawIndexed(rows, ctx.producerSlot, exhausted, key);
68
+ case "uniquePerIteration":
69
+ case "roundRobin":
70
+ // Index by THIS feeder's run-global draw count so a mix entry / overridden shared
71
+ // feeder stays contiguous; `?? globalIteration` keeps single-scenario parity.
72
+ return drawIndexed(rows, ctx.drawIndex ?? ctx.globalIteration, exhausted, key);
73
+ case "random":
74
+ return rows.length === 0
75
+ ? missDraw(exhausted)
76
+ : toValueDraw(rows[Math.floor(Math.random() * rows.length)], key);
77
+ case "weightedRandom": {
78
+ const picked = weight ? pickWeighted(rows, weight) : undefined;
79
+ return picked === undefined ? missDraw(exhausted) : toValueDraw(picked, key);
80
+ }
81
+ case "partitionByVu": {
82
+ const partition = ctx.producerCount > 0
83
+ ? rows.filter((_, i) => i % ctx.producerCount === ctx.producerSlot)
84
+ : rows.slice();
85
+ // Index within the VU partition by THIS feeder's per-slot draw count (mix-correct);
86
+ // `?? slotIteration` keeps single-scenario parity.
87
+ return drawIndexed(partition, ctx.slotDrawIndex ?? ctx.slotIteration, exhausted, key);
88
+ }
89
+ }
90
+ };
91
+ return {
92
+ __glubean_type: "load-feeder",
93
+ strategy,
94
+ exhausted,
95
+ ...(key !== undefined ? { key } : {}),
96
+ ...(weight !== undefined ? { weight } : {}),
97
+ size: rows.length,
98
+ allocate,
99
+ };
100
+ }
101
+ class FeederSourceImpl {
102
+ rows;
103
+ key;
104
+ constructor(rows, key) {
105
+ this.rows = rows;
106
+ this.key = key;
107
+ }
108
+ uniquePerVu(opts) {
109
+ return makeBinding(this.rows, "uniquePerVu", opts?.exhausted ?? "fail", this.key);
110
+ }
111
+ uniquePerIteration(opts) {
112
+ return makeBinding(this.rows, "uniquePerIteration", opts?.exhausted ?? "fail", this.key);
113
+ }
114
+ roundRobin(opts) {
115
+ return makeBinding(this.rows, "roundRobin", opts?.exhausted ?? "recycle", this.key);
116
+ }
117
+ random(opts) {
118
+ return makeBinding(this.rows, "random", opts?.exhausted ?? "recycle", this.key);
119
+ }
120
+ weightedRandom(opts) {
121
+ return makeBinding(this.rows, "weightedRandom", opts.exhausted ?? "recycle", this.key, opts.weight);
122
+ }
123
+ partitionByVu(opts) {
124
+ return makeBinding(this.rows, "partitionByVu", opts?.exhausted ?? "fail", this.key);
125
+ }
126
+ }
127
+ // =============================================================================
128
+ // Sources
129
+ // =============================================================================
130
+ /**
131
+ * Feeder data-source factories. `fromArray` is synchronous; `fromJson` /
132
+ * `fromCsv` read a file and must be awaited.
133
+ *
134
+ * @example
135
+ * ```ts
136
+ * const users = feeder.fromArray([{ userId: "u1" }, { userId: "u2" }], { key: "userId" });
137
+ * const products = await feeder.fromJson("./data/products.json", { key: "sku" });
138
+ * loadRunner("checkout", {
139
+ * scenario,
140
+ * concurrency: 300,
141
+ * feeders: {
142
+ * user: users.uniquePerVu({ exhausted: "fail" }),
143
+ * product: products.weightedRandom({ weight: "trafficWeight" }),
144
+ * },
145
+ * input: ({ feed }) => ({ user: feed.user, product: feed.product }),
146
+ * });
147
+ * ```
148
+ */
149
+ export const feeder = {
150
+ /** In-memory rows. */
151
+ fromArray(rows, opts) {
152
+ return new FeederSourceImpl(rows, opts?.key);
153
+ },
154
+ /** Load rows from a JSON file (array, or `pick` a nested array). Await it. */
155
+ async fromJson(path, opts) {
156
+ const rows = (await loadJson(path, opts?.pick ? { pick: opts.pick } : undefined));
157
+ return new FeederSourceImpl(rows, opts?.key);
158
+ },
159
+ /** Load rows from a CSV/TSV file. Await it. */
160
+ async fromCsv(path, opts) {
161
+ const loaderOpts = {};
162
+ if (opts?.separator !== undefined)
163
+ loaderOpts.separator = opts.separator;
164
+ if (opts?.headers !== undefined)
165
+ loaderOpts.headers = opts.headers;
166
+ const rows = (await loadCsv(path, loaderOpts));
167
+ return new FeederSourceImpl(rows, opts?.key);
168
+ },
169
+ };
170
+ //# sourceMappingURL=feeder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feeder.js","sourceRoot":"","sources":["../../src/load/feeder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * `@glubean/sdk/load` — first-class single-node load testing.
3
+ *
4
+ * Authoring surface for performance transactions (`loadScenario()`) and the
5
+ * pressure plans that execute them (`loadRunner()`). This subpath intentionally
6
+ * stays separate from the main `@glubean/sdk` entry so ordinary test authoring
7
+ * is not widened by load-only concepts.
8
+ *
9
+ * Boundary:
10
+ * contract() / workflow() / test() = correctness + evidence
11
+ * loadScenario() = a repeatable performance transaction
12
+ * loadRunner() = how much pressure to apply
13
+ *
14
+ * NOTE (M1): this is the static authoring surface only. Actual load execution
15
+ * lives in @glubean/runner and ships in later milestones.
16
+ */
17
+ export type { LoadContext, LoadProducerSlot, LoadIteration, LoadReportSignal, LoadPrimaryCompletionReceipt, LoadOmittedContextKeys, } from "./context.js";
18
+ export type { LoadStepOptions, LoadAssertionFailureMode, LoadSetupFunction, LoadStepFunction, LoadTeardownFunction, } from "./step.js";
19
+ export { loadScenario, LoadBuilder } from "./builder.js";
20
+ export { isLoadBranchStep, isLoadPollStep } from "./scenario.js";
21
+ export type { LoadScenario, LoadScenarioMeta, LoadStepMeta, LoadStepDefinition, LoadBranchData, LoadPollData, LoadConditionSpec, LoadPollOpts, LoadFragmentBuilder, } from "./scenario.js";
22
+ export { loadRunner, loadMixEntry } from "./runner.js";
23
+ export type { LoadPlan, LoadRunnerConfig, LoadMixConfig, LoadMixEntry, AnyLoadRunnerConfig, LoadInputOption, LoadInputArgs, LoadDuration, LoadContinuationConfig, LoadPacingConfig, LoadThresholds, LoadThresholdScope, LoadReportConfig, LoadScenarioRef, LoadProducerSlotInfo, LoadIterationInfo, } from "./runner.js";
24
+ export { projectLoadPlan } from "./projection.js";
25
+ export type { LoadProjection, LoadScenarioRefProjection } from "./projection.js";
26
+ export { parseDurationMs } from "./duration.js";
27
+ export type * from "./artifact.js";
28
+ export type { LoadEvent, LoadEventEnvelope, LoadEventOf, LoadEndReason, LoadRouteKeySource, LoadResolvedConfig, } from "./events.js";
29
+ export type { LoadReducer, LoadProgressSnapshot, LoadFailureSummary, } from "./progress.js";
30
+ export { feeder } from "./feeder.js";
31
+ export type { FeederBinding, FeederSource, FeederSourceOptions, FeederStrategy, ExhaustedPolicy, FeederStrategyOptions, WeightedRandomOptions, FeederDrawContext, FeederDraw, } from "./feeder.js";
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/load/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,eAAe,EACf,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEjE,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvD,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEjF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,mBAAmB,eAAe,CAAC;AAEnC,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,YAAY,EACV,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,UAAU,GACX,MAAM,aAAa,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { loadScenario, LoadBuilder } from "./builder.js";
2
+ export { isLoadBranchStep, isLoadPollStep } from "./scenario.js";
3
+ export { loadRunner, loadMixEntry } from "./runner.js";
4
+ export { projectLoadPlan } from "./projection.js";
5
+ export { parseDurationMs } from "./duration.js";
6
+ export { feeder } from "./feeder.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/load/index.ts"],"names":[],"mappings":"AAiCA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAcjE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqBvD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAmBhD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Live progress + reducer contract for the load runtime.
3
+ *
4
+ * Progress is NOT a second raw event stream: CLI / Cloud read `reducer.snapshot()`
5
+ * on a fixed interval, and the final `LoadArtifact` comes from the same reducer
6
+ * state — so live progress and the report never diverge.
7
+ */
8
+ import type { LoadArtifact, LoadEndpointSummary, LoadErrorKind, Percentiles } from "./artifact.js";
9
+ import type { LoadEvent } from "./events.js";
10
+ /** A brief failure summary surfaced in live progress (not the full trace sample). */
11
+ export interface LoadFailureSummary {
12
+ scenarioId?: string;
13
+ scenarioRefId?: string;
14
+ iterationId: string;
15
+ errorKind?: LoadErrorKind;
16
+ failedStepName?: string;
17
+ message?: string;
18
+ /** Offset from run start, in ms. */
19
+ atMs: number;
20
+ }
21
+ /** A point-in-time progress snapshot, derived from reducer state. */
22
+ export interface LoadProgressSnapshot {
23
+ elapsedMs: number;
24
+ requestedConcurrency: number;
25
+ primaryInFlight: number;
26
+ continuationInFlight: number;
27
+ blockedOnBacklog: number;
28
+ primaryStarted: number;
29
+ primaryCompleted: number;
30
+ endToEndCompleted: number;
31
+ inFlightAtEnd?: number;
32
+ failedIterations: number;
33
+ /** End-to-end compatibility view (ambiguous once producer release is on). */
34
+ throughputPerSec: number;
35
+ /** End-to-end compatibility view. */
36
+ transactionLatency: Percentiles;
37
+ primaryThroughputPerSec?: number;
38
+ endToEndThroughputPerSec?: number;
39
+ continuationBacklog?: number;
40
+ oldestContinuationAgeMs?: number;
41
+ slotOccupancyByPhase?: Record<"primary" | "continuation" | "blockedOnBacklog", number>;
42
+ topSlowEndpoints: LoadEndpointSummary[];
43
+ recentFailures: LoadFailureSummary[];
44
+ }
45
+ /**
46
+ * Streaming reducer: fold the `LoadEvent` fact stream into bounded counters /
47
+ * histograms / reservoirs, expose live `snapshot()`, and `finalize()` to the
48
+ * versioned `LoadArtifact`. The implementation (bounded, no full-sample arrays)
49
+ * lives in @glubean/runner.
50
+ */
51
+ export interface LoadReducer {
52
+ apply(event: LoadEvent): void;
53
+ snapshot(now?: number): LoadProgressSnapshot;
54
+ finalize(): LoadArtifact;
55
+ }
56
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/load/progress.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACnG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,gBAAgB,EAAE,MAAM,CAAC;IACzB,qCAAqC;IACrC,kBAAkB,EAAE,WAAW,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC,SAAS,GAAG,cAAc,GAAG,kBAAkB,EAAE,MAAM,CAAC,CAAC;IACvF,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;IACxC,cAAc,EAAE,kBAAkB,EAAE,CAAC;CACtC;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAAC;IAC7C,QAAQ,IAAI,YAAY,CAAC;CAC1B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/load/progress.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ import type { AnyLoadRunnerConfig } from "./runner.js";
2
+ /** One scenario reference within a projected plan. */
3
+ export interface LoadScenarioRefProjection {
4
+ /** Traffic-mix entry id, if this came from a mix. */
5
+ scenarioRefId?: string;
6
+ /** The referenced loadScenario id. */
7
+ scenarioId: string;
8
+ /** Traffic-mix weight, if any. */
9
+ weight?: number;
10
+ /** Top-level step names (for display). */
11
+ steps: string[];
12
+ }
13
+ /** Static, discovery-facing summary of a load plan. */
14
+ export interface LoadProjection {
15
+ runnerId: string;
16
+ runMode: "load";
17
+ concurrency: number;
18
+ durationMs?: number;
19
+ iterations?: number;
20
+ rampUpMs?: number;
21
+ scenarios: LoadScenarioRefProjection[];
22
+ /** Which threshold scopes are configured (transaction / endpoints / steps / …). */
23
+ thresholdScopes: string[];
24
+ }
25
+ /**
26
+ * Project a load plan into a static `LoadProjection` (pure; no execution).
27
+ *
28
+ * Takes the plan core (`id` + `config`) rather than a full `LoadPlan`, so
29
+ * `loadRunner()` can compute and attach the projection while constructing the
30
+ * plan (avoiding a `projection`-field self-reference).
31
+ */
32
+ export declare function projectLoadPlan(plan: {
33
+ id: string;
34
+ config: AnyLoadRunnerConfig;
35
+ }): LoadProjection;
36
+ //# sourceMappingURL=projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../src/load/projection.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,aAAa,CAAC;AAGxE,sDAAsD;AACtD,MAAM,WAAW,yBAAyB;IACxC,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,yBAAyB,EAAE,CAAC;IACvC,mFAAmF;IACnF,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAaD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,GAAG,cAAc,CA6BjG"}
@@ -0,0 +1,47 @@
1
+ import { parseDurationMs } from "./duration.js";
2
+ function resolveScenario(ref) {
3
+ if (ref.__glubean_type === "load-scenario-builder") {
4
+ return ref.build();
5
+ }
6
+ return ref;
7
+ }
8
+ function stepNames(scenario) {
9
+ return scenario.steps.map((step) => step.meta.name);
10
+ }
11
+ /**
12
+ * Project a load plan into a static `LoadProjection` (pure; no execution).
13
+ *
14
+ * Takes the plan core (`id` + `config`) rather than a full `LoadPlan`, so
15
+ * `loadRunner()` can compute and attach the projection while constructing the
16
+ * plan (avoiding a `projection`-field self-reference).
17
+ */
18
+ export function projectLoadPlan(plan) {
19
+ const cfg = plan.config;
20
+ const scenarios = [];
21
+ if ("scenarios" in cfg) {
22
+ for (const entry of cfg.scenarios) {
23
+ const scenario = resolveScenario(entry.scenario);
24
+ scenarios.push({
25
+ scenarioRefId: entry.id,
26
+ scenarioId: scenario.meta.id,
27
+ weight: entry.weight,
28
+ steps: stepNames(scenario),
29
+ });
30
+ }
31
+ }
32
+ else {
33
+ const scenario = resolveScenario(cfg.scenario);
34
+ scenarios.push({ scenarioId: scenario.meta.id, steps: stepNames(scenario) });
35
+ }
36
+ return {
37
+ runnerId: plan.id,
38
+ runMode: "load",
39
+ concurrency: cfg.concurrency,
40
+ ...(cfg.duration !== undefined ? { durationMs: parseDurationMs(cfg.duration) } : {}),
41
+ ...(cfg.iterations !== undefined ? { iterations: cfg.iterations } : {}),
42
+ ...(cfg.rampUp !== undefined ? { rampUpMs: parseDurationMs(cfg.rampUp) } : {}),
43
+ scenarios,
44
+ thresholdScopes: cfg.thresholds ? Object.keys(cfg.thresholds) : [],
45
+ };
46
+ }
47
+ //# sourceMappingURL=projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.js","sourceRoot":"","sources":["../../src/load/projection.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AA6BhD,SAAS,eAAe,CAAC,GAAoB;IAC3C,IAAK,GAAmC,CAAC,cAAc,KAAK,uBAAuB,EAAE,CAAC;QACpF,OAAQ,GAAmB,CAAC,KAAK,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,GAAmB,CAAC;AAC7B,CAAC;AAED,SAAS,SAAS,CAAC,QAAsB;IACvC,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAiD;IAC/E,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;IACxB,MAAM,SAAS,GAAgC,EAAE,CAAC;IAElD,IAAI,WAAW,IAAI,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;YAClC,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACjD,SAAS,CAAC,IAAI,CAAC;gBACb,aAAa,EAAE,KAAK,CAAC,EAAE;gBACvB,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE;gBAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,KAAK,EAAE,SAAS,CAAC,QAAQ,CAAC;aAC3B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,SAAS,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,EAAE;QACjB,OAAO,EAAE,MAAM;QACf,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,GAAG,CAAC,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,SAAS;QACT,eAAe,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE;KACnE,CAAC;AACJ,CAAC"}