@kradle/challenges-sdk 0.14.1 → 0.15.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 +17 -1
- package/LLM_README.md +13 -14
- package/MIGRATION-0.13.md +5 -1
- package/README.md +16 -18
- package/dist/runtime/builder.d.ts +3 -3
- package/dist/runtime/builder.d.ts.map +1 -1
- package/dist/runtime/reducer.js +1 -1
- package/dist/runtime/reducer.js.map +1 -1
- package/dist/runtime/types.d.ts +3 -3
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/test/harness.d.ts +19 -18
- package/dist/test/harness.d.ts.map +1 -1
- package/dist/test/harness.js +54 -47
- package/dist/test/harness.js.map +1 -1
- package/dist/test/helpers.js +1 -1
- package/dist/test/helpers.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,21 @@ also hand-edit this file or the [Unreleased] section at any time.
|
|
|
17
17
|
|
|
18
18
|
## [Unreleased]
|
|
19
19
|
|
|
20
|
+
## [0.15.0] - 2026-09-18
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Two reads on the test kit's `Game`: `game.participants` gives every participant's record by name (the observations, `state`, `score`) and `game.votes` gives every vote's record by id (`open`, `round`, `cast`). Both are read-only. `scores(game)` is unchanged.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **Breaking:** `game.participant(name)` returns a read-only record. A test that wrote through the record no longer compiles; drive the state through the fake player and the events.
|
|
29
|
+
- The guides name what happens, not the machinery that does it: `README.md`, `LLM_README.md` and `MIGRATION-0.13.md`, all three in the package, no longer speak of the arena, the reducer or the sandbox, and the JSDoc on the four entries says the same. A challenge is a set of pure rules that Kradle runs, and `kradle challenge test` runs them against the built bundle, with the limits of a run: no clock, no random, no network. In `LLM_README.md` the "Rules of the Reducer" section is now "Constraints".
|
|
30
|
+
|
|
31
|
+
### Removed
|
|
32
|
+
|
|
33
|
+
- **Breaking:** The test kit no longer exposes `game.reducerState` or the `ReducerState` type. Read the players through `game.participants` and the votes through `game.votes`; `JSON.parse(game.checkpoint())` gives the whole state. See "The test kit after 0.14.1" in `MIGRATION-0.13.md`.
|
|
34
|
+
|
|
20
35
|
## [0.14.1] - 2026-09-18
|
|
21
36
|
|
|
22
37
|
### Changed
|
|
@@ -214,7 +229,8 @@ also hand-edit this file or the [Unreleased] section at any time.
|
|
|
214
229
|
- Voting primitives (`votedFor`, `promptVote`, `allVotesIn`, `assignDefaultVotes`) for challenges that use discuss-then-vote-then-act phases as an alternative to pad-based voting.
|
|
215
230
|
- Build-time validation of vote IDs and options against `KRADLE_CHALLENGE_VOTING_OPTIONS` (when set), matching the existing `getLocation`/`setEndState` pattern. `promptVote` also validates each announced option against the declared `votingOptions`.
|
|
216
231
|
|
|
217
|
-
[Unreleased]: https://github.com/Kradle-ai/challenges-sdk/compare/v0.
|
|
232
|
+
[Unreleased]: https://github.com/Kradle-ai/challenges-sdk/compare/v0.15.0...HEAD
|
|
233
|
+
[0.15.0]: https://github.com/Kradle-ai/challenges-sdk/compare/v0.14.1...v0.15.0
|
|
218
234
|
[0.14.1]: https://github.com/Kradle-ai/challenges-sdk/compare/v0.14.0...v0.14.1
|
|
219
235
|
[0.14.0]: https://github.com/Kradle-ai/challenges-sdk/compare/v0.13.1...v0.14.0
|
|
220
236
|
[0.13.1]: https://github.com/Kradle-ai/challenges-sdk/compare/v0.13.0...v0.13.1
|
package/LLM_README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# LLM_README.md - @kradle/challenges-sdk API Reference
|
|
2
2
|
|
|
3
|
-
This document is the API reference for AI agents that write Kradle challenges with `@kradle/challenges-sdk`. A challenge is a
|
|
3
|
+
This document is the API reference for AI agents that write Kradle challenges with `@kradle/challenges-sdk`. A challenge is a set of pure rules that Kradle runs during the game. Read this file before you write a challenge. The declarations (`.d.ts`) carry the full JSDoc of every member; this file is the tutorial and the index.
|
|
4
4
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ This document is the API reference for AI agents that write Kradle challenges wi
|
|
|
13
13
|
7. [The Context](#the-context)
|
|
14
14
|
8. [Players and Entities](#players-and-entities)
|
|
15
15
|
9. [Structures](#structures)
|
|
16
|
-
10. [
|
|
16
|
+
10. [Constraints](#constraints)
|
|
17
17
|
11. [Testing](#testing)
|
|
18
18
|
12. [Build and Run](#build-and-run)
|
|
19
19
|
13. [Complete Examples](#complete-examples)
|
|
@@ -25,11 +25,11 @@ This document is the API reference for AI agents that write Kradle challenges wi
|
|
|
25
25
|
|
|
26
26
|
## Overview
|
|
27
27
|
|
|
28
|
-
`@kradle/challenges-sdk` is a TypeScript SDK for Minecraft challenges that AI agents play on Kradle. A challenge is one root call, `defineChallenge(config, decl)`, plus steps that register the behavior: `.setup(...)`, `.start(...)`, `.phase(name, {...})`, `.on({...})`, `.outcome({...})`. The
|
|
28
|
+
`@kradle/challenges-sdk` is a TypeScript SDK for Minecraft challenges that AI agents play on Kradle. A challenge is one root call, `defineChallenge(config, decl)`, plus steps that register the behavior: `.setup(...)`, `.start(...)`, `.phase(name, {...})`, `.on({...})`, `.outcome({...})`. The game server reports the facts (players, entities, loaded chunks, block changes, containers, chat, deaths, pickups, votes) every server tick, and applies the effects the rules ask for (give, fill, teleport, titles, votes, the end of the game). The state is plain JSON, and a run replays from its event log.
|
|
29
29
|
|
|
30
|
-
There is no datapack and no mcfunction. The rules are TypeScript, the tests run without Minecraft, and `kradle challenge test` runs them
|
|
30
|
+
There is no datapack and no mcfunction. The rules are TypeScript, the tests run without Minecraft, and `kradle challenge test` runs them against the built bundle, with the limits of a run.
|
|
31
31
|
|
|
32
|
-
The package's entries: `@kradle/challenges-sdk` (the author API), `@kradle/challenges-sdk/test` (the test kit), `@kradle/challenges-sdk/engine` (the wire protocol, for
|
|
32
|
+
The package's entries: `@kradle/challenges-sdk` (the author API), `@kradle/challenges-sdk/test` (the test kit), `@kradle/challenges-sdk/engine` (the wire protocol, for tools).
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
@@ -40,7 +40,7 @@ Use [Kradle's CLI](https://github.com/kradle-ai/cli):
|
|
|
40
40
|
```bash
|
|
41
41
|
kradle init # a project with the SDK installed
|
|
42
42
|
kradle challenge create my-challenge # challenges/my-challenge/{challenge.ts,config.ts,challenge.test.ts}
|
|
43
|
-
kradle challenge test my-challenge # the tests,
|
|
43
|
+
kradle challenge test my-challenge # the tests, against the built bundle
|
|
44
44
|
kradle challenge build my-challenge # the bundle, uploaded and activated
|
|
45
45
|
kradle challenge run my-challenge # a run in the cloud
|
|
46
46
|
```
|
|
@@ -53,7 +53,7 @@ A challenge folder holds `challenge.ts` (the rules), `config.ts` (the metadata a
|
|
|
53
53
|
|
|
54
54
|
## Core Concepts
|
|
55
55
|
|
|
56
|
-
**The
|
|
56
|
+
**The rules.** Every event from the game server goes through the challenge's rules, which return the next state and a list of actions. The rules never keep state outside the returned state, never mutate their input, and never touch the clock, the network or the file system: during a run, `Date.now()`, `Math.random()`, timers, `process` and `fetch` do not exist.
|
|
57
57
|
|
|
58
58
|
**The state.** `g.state` (shared) and `p.state` (per player). Both come from the initializers in the root declaration (`state: { game: (init) => ({...}), player: (p, init) => ({...}) }`). The SDK keeps its own fields beside them: `p.score`, `p.pos`, `p.inventory`, `p.isActive`... The whole state is JSON.
|
|
59
59
|
|
|
@@ -249,7 +249,7 @@ export default challenge;
|
|
|
249
249
|
|
|
250
250
|
---
|
|
251
251
|
|
|
252
|
-
##
|
|
252
|
+
## Constraints
|
|
253
253
|
|
|
254
254
|
- Every callback is synchronous. A callback that returns a Promise is an error that ends the run.
|
|
255
255
|
- A phase request (`g.startPhase`, `g.endPhase`) applies once the event's handler group returned: every global `on` in order, then the phase's. A later handler of the same event still sees the current phase; a second request in the group throws `phase_twice`. `g.endGame` skips the later handlers of the event; the current callback continues.
|
|
@@ -260,21 +260,20 @@ export default challenge;
|
|
|
260
260
|
- The observations are read-only everywhere: `p.pos.y = 1`, `p.score = 3` or `g.params.x = 1` throws `read_only` (the state is written through `p.state` and `g.state`; the score through `g.setScore` / `g.addScore`).
|
|
261
261
|
- The pure callbacks (`outcome.*`, `judgeContext`, `until`, a functional `duration` or `next`, a vote's `accept`) read only: a write or an effect does not compile, and throws `read_only` at run time; so does a write in `onOver`.
|
|
262
262
|
- Derived scores (`outcome.scores`) commit once per reduction, after the handlers and after the transition the checkpoint made; every evaluation reads the previous committed scores, so `p.score + 1` adds one. `until` and `endWhen` read the vector under evaluation; `exit` and `enter` read the committed one.
|
|
263
|
-
- A vote request carries the round
|
|
263
|
+
- A vote request carries the round it saw (`vote_round`); a request without a round, or with an earlier one, is refused with feedback. The harness's `Fake.vote` stamps the current round.
|
|
264
264
|
- The engine confirms the setup batches in order; an acknowledgement that is not for the pending batch is logged and ignored.
|
|
265
265
|
|
|
266
266
|
---
|
|
267
267
|
|
|
268
268
|
## Testing
|
|
269
269
|
|
|
270
|
-
`@kradle/challenges-sdk/test` is a stand-in
|
|
270
|
+
`@kradle/challenges-sdk/test` is a stand-in for the run. No test framework dependency: it throws plain errors.
|
|
271
271
|
|
|
272
272
|
```ts
|
|
273
273
|
import { describe, expect, test } from "bun:test";
|
|
274
274
|
import { Game, sandboxed, scores } from "@kradle/challenges-sdk/test";
|
|
275
275
|
import source from "./challenge";
|
|
276
276
|
|
|
277
|
-
// Under `kradle challenge test`, the built bundle inside the arena's sandbox; the source otherwise.
|
|
278
277
|
const challenge = await sandboxed(source);
|
|
279
278
|
|
|
280
279
|
test("a kill scores", () => {
|
|
@@ -291,13 +290,13 @@ test("a kill scores", () => {
|
|
|
291
290
|
|
|
292
291
|
`Game.begin(seed, roster, opts)` sends `run_started`, the joins, one tick with every participant's position (a default row unless `at`), and confirms the setup batches. `game.player(name)` is a scripted player: `moveTo`, `says`, `vote(id, option)`, `hurt`, `dies`, `respawns`, `picksUp`, `setInventory`, `enters(zone)`, `exits(zone)`, `uses`, `breaks`, `places`, `joins`, `leaves`. The game feeds the mirror: `terrain`, `setBlocks`, `fillBlocks`, `spawnEntity`, `changeEntity`, `moveEntities`, `removeEntity`, `container`, `sample`, `other`; and answers the engine's side: `walkResult`, `batchResult`, `effectFailed`, `confirmSetup`. Time: `tick(n)`, `after(duration)`, `at(duration)`.
|
|
293
292
|
|
|
294
|
-
Reads: `game.state` (the shared data), `game.phase`, `game.status`, `game.participant(name)`, `game.
|
|
293
|
+
Reads: `game.state` (the shared data), `game.phase`, `game.status`, `game.participant(name)`, `game.participants`, `game.votes`, `game.of(type)` / `game.all(type)` (actions), `game.effects(kind)` / `game.effectsAll(kind)`, `game.said()`, `game.announcements(to?)`, `game.result()`, `game.logs()`, `game.metrics()`; `scores(g)` and `near(a, b, blocks)` from the same entry. `game.replay()` re-runs the log and compares; `game.checkpoint()` / `Game.resume(challenge, json)` cross a JSON round trip.
|
|
295
294
|
|
|
296
295
|
---
|
|
297
296
|
|
|
298
297
|
## Build and Run
|
|
299
298
|
|
|
300
|
-
`kradle challenge build <slug>` type-checks the project, bundles the challenge, loads the bundle
|
|
299
|
+
`kradle challenge build <slug>` type-checks the project, bundles the challenge, loads the bundle the way a run loads it, reads its manifest and runs one synthetic start (a definition or API error fails the build; a throw from the challenge's own code that needs the world is a warning), then uploads and activates it. `kradle challenge run <slug>` starts a run in the cloud.
|
|
301
300
|
|
|
302
301
|
The manifest the bundle exports (`runtime: 2`) carries the name, the life, the roles, the locations, the votes and the params. The backend checks the roles against the challenge's configuration at activation and stores the votes with the artifact.
|
|
303
302
|
|
|
@@ -439,4 +438,4 @@ export default challenge
|
|
|
439
438
|
- Use one chain by default, followed by `export default challenge;`. Split only to resolve a circular type; do not copy a split into every challenge.
|
|
440
439
|
- Prefer `outcome.scores` over manual score writes: the score is then a function of the state, computed after every event.
|
|
441
440
|
- Keep `p.state` small and JSON. Copy what you keep from an event (`{ ...e.pos }`).
|
|
442
|
-
- Test with `Game` before you build: a test is faster than a run, and `kradle challenge test` runs the same file
|
|
441
|
+
- Test with `Game` before you build: a test is faster than a run, and `kradle challenge test` runs the same file against the built bundle.
|
package/MIGRATION-0.13.md
CHANGED
|
@@ -85,7 +85,7 @@ The root declaration holds data and the state initializers: `state`, `life`, `du
|
|
|
85
85
|
| `effectFailed { kind, detail }` | `{ kind, detail, effect?, batch? }`; `g.batch(name, fn)` + `on.batchDone` |
|
|
86
86
|
| `ContextOf<typeof config, typeof state>`, `typeof challenge.ctx` | `CtxOf<typeof challenge>`, `ReadCtxOf`, `SetupCtxOf`, `PlayerIn<G>`; split the root call only to resolve a circular type |
|
|
87
87
|
| `game.state.status === "LOBBY"` (in a test) | `game.status === "CONNECTING"` (the author context has no `status` field in 0.12; a rule reads `g.status` now) |
|
|
88
|
-
| `Game.begin(seed, roster)` without positions | `begin` supplies a position per participant (`at` to choose); `g.state` is the shared data, `g.
|
|
88
|
+
| `Game.begin(seed, roster)` without positions | `begin` supplies a position per participant (`at` to choose); `g.state` is the shared data, `g.participants` every player's record; `Fake.has` is `setInventory`; `g.all("store")` is `g.all("metric")` |
|
|
89
89
|
|
|
90
90
|
## Helpers
|
|
91
91
|
|
|
@@ -126,3 +126,7 @@ A root predicate (`votes.room.accept`) cannot call a helper typed from the chall
|
|
|
126
126
|
Remove the `markers` declaration. Replace `g.markers(tag)` with `g.entities({ tag })` and `marker.at` with `entity.pos`.
|
|
127
127
|
All non-player entities in loaded chunks are available before setup. Minecraft controls chunk loading; the SDK does not preload a box. Keep entities needed for setup in spawn chunks or near the players' initial positions. Distant entities appear only after Minecraft loads their chunks.
|
|
128
128
|
In tests, use `game.spawnEntity(id, type, pos, { tags })` before `game.begin(...)` instead of `begin(..., { markers })`.
|
|
129
|
+
|
|
130
|
+
## The test kit after 0.14.1
|
|
131
|
+
|
|
132
|
+
`game.reducerState` and the `ReducerState` type are gone. Read the players through `game.participants` (every record, by name) or `game.participant(name)`, the votes through `game.votes` (by id), and the whole state, when a test needs it, through `JSON.parse(game.checkpoint())`. `scores(game)` is unchanged.
|
package/README.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
# @kradle/challenges-sdk
|
|
4
4
|
|
|
5
|
-
Write a Minecraft challenge for Kradle as a
|
|
6
|
-
that
|
|
7
|
-
for effects. The
|
|
8
|
-
|
|
5
|
+
Write a Minecraft challenge for Kradle as a set of pure rules: TypeScript
|
|
6
|
+
functions that read the world and the players, update a JSON state, and ask
|
|
7
|
+
the game server for effects. The server reports the facts and applies the
|
|
8
|
+
effects; the rules run with no clock, no `Math.random()` and no network.
|
|
9
9
|
|
|
10
10
|
## Getting started
|
|
11
11
|
|
|
@@ -15,13 +15,13 @@ the CLI's README first.
|
|
|
15
15
|
```bash
|
|
16
16
|
kradle init
|
|
17
17
|
kradle challenge create my-challenge # challenges/my-challenge/{challenge.ts,config.ts,challenge.test.ts}
|
|
18
|
-
kradle challenge test my-challenge # the tests,
|
|
18
|
+
kradle challenge test my-challenge # the tests, against the built bundle
|
|
19
19
|
kradle challenge build my-challenge # the bundle, uploaded and activated
|
|
20
20
|
kradle challenge run my-challenge # a run in the cloud
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
A manual installation is one dependency: `npm install @kradle/challenges-sdk@next`
|
|
24
|
-
(the
|
|
24
|
+
(the SDK stays under the npm tag `next` until the CLI release installs it).
|
|
25
25
|
Add `"type": "module"` to the project's `package.json`.
|
|
26
26
|
|
|
27
27
|
## Local development
|
|
@@ -144,15 +144,15 @@ export const pillarDone = (g: StructureReads, at: { x: number; y: number; z: num
|
|
|
144
144
|
|
|
145
145
|
## Testing
|
|
146
146
|
|
|
147
|
-
`@kradle/challenges-sdk/test` is a stand-in
|
|
148
|
-
the actions, and checks the state; `replay()` proves determinism.
|
|
147
|
+
`@kradle/challenges-sdk/test` is a stand-in for the run. A test feeds events,
|
|
148
|
+
reads the actions, and checks the state; `replay()` proves determinism.
|
|
149
149
|
|
|
150
150
|
```ts
|
|
151
151
|
import { describe, expect, test } from "bun:test";
|
|
152
152
|
import { Game, sandboxed, scores } from "@kradle/challenges-sdk/test";
|
|
153
153
|
import source from "./challenge";
|
|
154
154
|
|
|
155
|
-
const challenge = await sandboxed(source);
|
|
155
|
+
const challenge = await sandboxed(source);
|
|
156
156
|
|
|
157
157
|
test("a tag scores", () => {
|
|
158
158
|
const g = new Game(challenge).begin(1, { Alice: "seeker", Bob: "hider" });
|
|
@@ -169,16 +169,14 @@ joins and confirms the setup batches. `g.player(name)` scripts a player
|
|
|
169
169
|
(`moveTo`, `says`, `vote`, `hurt`, `dies`, `setInventory`, `places`, ...); the
|
|
170
170
|
game feeds the mirror (`terrain`, `setBlocks`, `spawnEntity`, `container`) and
|
|
171
171
|
answers the engine's side (`walkResult`, `batchResult`). `kradle challenge test
|
|
172
|
-
<slug>` runs the same file against the built bundle
|
|
172
|
+
<slug>` runs the same file against the built bundle, with the limits of a run.
|
|
173
173
|
|
|
174
174
|
## Build and run
|
|
175
175
|
|
|
176
176
|
`kradle challenge build <slug>` bundles `challenge.ts` into one file, loads it
|
|
177
|
-
once
|
|
178
|
-
configuration. The
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
types catch. The engine contract (`Event`, `Effect`, `Action`) is in
|
|
184
|
-
`src/runtime/sdk.ts`; the server side is `backend/engine-plugin`.
|
|
177
|
+
once the way a run loads it, uploads it and activates it with the challenge's
|
|
178
|
+
configuration. The run's event log is uploaded as the `runtime` recording.
|
|
179
|
+
|
|
180
|
+
The wire contract (`Event`, `Effect`, `Action`) is the
|
|
181
|
+
`@kradle/challenges-sdk/engine` entry; `test/types/` shows what the types
|
|
182
|
+
catch.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type State } from "./reducer.js";
|
|
2
2
|
import type { ChallengeApi, ChallengeConfig, Decl, Handlers, Outcome, PhaseSpec, PlayerMap, ResolvePlayers, VotesDecl } from "./types.js";
|
|
3
3
|
import type { Action, Event, RuntimeManifest } from "./wire.js";
|
|
4
|
-
/** A challenge as
|
|
4
|
+
/** A challenge as a run and the harness use it: the API plus `init`, `reduce` and the manifest. */
|
|
5
5
|
export interface Challenge<C extends ChallengeConfig, G, PM extends PlayerMap<C>, Ph extends string, Z extends string, T extends string, V extends VotesDecl> extends ChallengeApi<C, G, PM, Ph, Z, T, V> {
|
|
6
|
-
/** The manifest
|
|
6
|
+
/** The manifest Kradle reads before a run. Reading it locks the definition. */
|
|
7
7
|
readonly manifest: RuntimeManifest;
|
|
8
8
|
/** True once the definition is locked (`init()` or `manifest` was used). */
|
|
9
9
|
readonly locked: boolean;
|
|
@@ -13,7 +13,7 @@ export interface Challenge<C extends ChallengeConfig, G, PM extends PlayerMap<C>
|
|
|
13
13
|
reduce(state: State, event: Event): {
|
|
14
14
|
/** The next state, frozen; the input is never changed. */
|
|
15
15
|
state: State;
|
|
16
|
-
/** What the
|
|
16
|
+
/** What the game server applies, in order. */
|
|
17
17
|
actions: Action[];
|
|
18
18
|
};
|
|
19
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/runtime/builder.ts"],"names":[],"mappings":"AAYA,OAAO,EAAwF,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AAEhI,OAAO,KAAK,EACX,YAAY,EACZ,eAAe,EACf,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,SAAS,EACT,SAAS,EACT,cAAc,EACd,SAAS,EAET,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,MAAM,EAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAIrE,
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/runtime/builder.ts"],"names":[],"mappings":"AAYA,OAAO,EAAwF,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AAEhI,OAAO,KAAK,EACX,YAAY,EACZ,eAAe,EACf,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,SAAS,EACT,SAAS,EACT,cAAc,EACd,SAAS,EAET,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,MAAM,EAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAIrE,mGAAmG;AACnG,MAAM,WAAW,SAAS,CACzB,CAAC,SAAS,eAAe,EACzB,CAAC,EACD,EAAE,SAAS,SAAS,CAAC,CAAC,CAAC,EACvB,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,SAAS,CAClB,SAAQ,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5C,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,iEAAiE;IACjE,IAAI,IAAI,KAAK,CAAC;IACd,2FAA2F;IAC3F,MAAM,CACL,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,GACV;QACF,0DAA0D;QAC1D,KAAK,EAAE,KAAK,CAAC;QACb,8CAA8C;QAC9C,OAAO,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC;AAyH9I;;;GAGG;AACH,wBAAgB,eAAe,CAC9B,KAAK,CAAC,CAAC,SAAS,eAAe,EAC/B,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACxC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACxC,EAAE,SAAS,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EACrE,KAAK,CAAC,EAAE,SAAS,MAAM,GAAG,KAAK,EAC/B,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EAC9B,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EAC9B,KAAK,CAAC,CAAC,SAAS,SAAS,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAC/C,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAiMzG;AAED,KAAK,OAAO,CAAC,CAAC,SAAS,eAAe,IAAI,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;AAGpE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/runtime/reducer.js
CHANGED
|
@@ -1919,7 +1919,7 @@ function createReducer(def) {
|
|
|
1919
1919
|
return;
|
|
1920
1920
|
}
|
|
1921
1921
|
if (e.round === undefined) {
|
|
1922
|
-
reject(`Your vote for "${e.voteId}" carries no round;
|
|
1922
|
+
reject(`Your vote for "${e.voteId}" carries no round; Kradle stamps every request with the round it saw.`);
|
|
1923
1923
|
return;
|
|
1924
1924
|
}
|
|
1925
1925
|
if (e.round !== v.round) {
|