@couch-kit/core 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.
- package/CHANGELOG.md +6 -0
- package/dist/index.js +23 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/replay.d.ts +42 -0
- package/lib/replay.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/replay.ts +80 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @couch-kit/core
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#21](https://github.com/faluciano/react-native-couch-kit/pull/21) [`f1e836d`](https://github.com/faluciano/react-native-couch-kit/commit/f1e836d8f17821f0da20db7c3c552552c9b22133) Thanks [@faluciano](https://github.com/faluciano)! - Add `replayActions` utility function for replaying recorded game sessions against a reducer. Includes `Recording`, `RecordedAction`, `StateSnapshot`, and `ReplayResult` types.
|
|
8
|
+
|
|
3
9
|
## 0.7.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/dist/index.js
CHANGED
|
@@ -200,8 +200,31 @@ function toErrorMessage(error) {
|
|
|
200
200
|
return error.message;
|
|
201
201
|
return String(error);
|
|
202
202
|
}
|
|
203
|
+
// src/replay.ts
|
|
204
|
+
function replayActions(recording, reducer) {
|
|
205
|
+
const snapshots = [];
|
|
206
|
+
let currentState = recording.initialState;
|
|
207
|
+
for (let i = 0;i < recording.actions.length; i++) {
|
|
208
|
+
const { action, timestamp } = recording.actions[i];
|
|
209
|
+
currentState = reducer(currentState, action);
|
|
210
|
+
snapshots.push({
|
|
211
|
+
state: currentState,
|
|
212
|
+
action,
|
|
213
|
+
timestamp,
|
|
214
|
+
index: i
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
const endTimestamp = recording.endTimestamp ?? (recording.actions.length > 0 ? recording.actions[recording.actions.length - 1].timestamp : recording.startTimestamp);
|
|
218
|
+
return {
|
|
219
|
+
finalState: currentState,
|
|
220
|
+
snapshots,
|
|
221
|
+
duration: endTimestamp - recording.startTimestamp,
|
|
222
|
+
actionCount: recording.actions.length
|
|
223
|
+
};
|
|
224
|
+
}
|
|
203
225
|
export {
|
|
204
226
|
toErrorMessage,
|
|
227
|
+
replayActions,
|
|
205
228
|
isValidSecret,
|
|
206
229
|
generateId,
|
|
207
230
|
derivePlayerIdLegacy,
|
package/lib/index.d.ts
CHANGED
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC"}
|
package/lib/replay.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { GameReducer, IAction, IGameState } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* A recorded action with timing metadata.
|
|
4
|
+
*/
|
|
5
|
+
export interface RecordedAction<A extends IAction = IAction> {
|
|
6
|
+
action: A;
|
|
7
|
+
timestamp: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A snapshot of state at a point in time during replay.
|
|
11
|
+
*/
|
|
12
|
+
export interface StateSnapshot<S extends IGameState = IGameState> {
|
|
13
|
+
state: S;
|
|
14
|
+
action: IAction;
|
|
15
|
+
timestamp: number;
|
|
16
|
+
index: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A recording that can be replayed against a reducer.
|
|
20
|
+
*/
|
|
21
|
+
export interface Recording<S extends IGameState = IGameState, A extends IAction = IAction> {
|
|
22
|
+
initialState: S;
|
|
23
|
+
actions: RecordedAction<A>[];
|
|
24
|
+
startTimestamp: number;
|
|
25
|
+
endTimestamp?: number;
|
|
26
|
+
metadata?: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The result of replaying a recording.
|
|
30
|
+
*/
|
|
31
|
+
export interface ReplayResult<S extends IGameState = IGameState> {
|
|
32
|
+
finalState: S;
|
|
33
|
+
snapshots: StateSnapshot<S>[];
|
|
34
|
+
duration: number;
|
|
35
|
+
actionCount: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Replays a recording against a reducer, producing the final state
|
|
39
|
+
* and intermediate snapshots for each action applied.
|
|
40
|
+
*/
|
|
41
|
+
export declare function replayActions<S extends IGameState = IGameState, A extends IAction = IAction>(recording: Recording<S, A>, reducer: GameReducer<S, A>): ReplayResult<S>;
|
|
42
|
+
//# sourceMappingURL=replay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO;IACzD,MAAM,EAAE,CAAC,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IAC9D,KAAK,EAAE,CAAC,CAAC;IACT,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,SAAS,CACxB,CAAC,SAAS,UAAU,GAAG,UAAU,EACjC,CAAC,SAAS,OAAO,GAAG,OAAO;IAE3B,YAAY,EAAE,CAAC,CAAC;IAChB,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IAC7D,UAAU,EAAE,CAAC,CAAC;IACd,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,CAAC,SAAS,UAAU,GAAG,UAAU,EACjC,CAAC,SAAS,OAAO,GAAG,OAAO,EAC3B,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CA4BzE"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
package/src/replay.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { GameReducer, IAction, IGameState } from "./types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A recorded action with timing metadata.
|
|
5
|
+
*/
|
|
6
|
+
export interface RecordedAction<A extends IAction = IAction> {
|
|
7
|
+
action: A;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A snapshot of state at a point in time during replay.
|
|
13
|
+
*/
|
|
14
|
+
export interface StateSnapshot<S extends IGameState = IGameState> {
|
|
15
|
+
state: S;
|
|
16
|
+
action: IAction;
|
|
17
|
+
timestamp: number;
|
|
18
|
+
index: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A recording that can be replayed against a reducer.
|
|
23
|
+
*/
|
|
24
|
+
export interface Recording<
|
|
25
|
+
S extends IGameState = IGameState,
|
|
26
|
+
A extends IAction = IAction,
|
|
27
|
+
> {
|
|
28
|
+
initialState: S;
|
|
29
|
+
actions: RecordedAction<A>[];
|
|
30
|
+
startTimestamp: number;
|
|
31
|
+
endTimestamp?: number;
|
|
32
|
+
metadata?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The result of replaying a recording.
|
|
37
|
+
*/
|
|
38
|
+
export interface ReplayResult<S extends IGameState = IGameState> {
|
|
39
|
+
finalState: S;
|
|
40
|
+
snapshots: StateSnapshot<S>[];
|
|
41
|
+
duration: number;
|
|
42
|
+
actionCount: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Replays a recording against a reducer, producing the final state
|
|
47
|
+
* and intermediate snapshots for each action applied.
|
|
48
|
+
*/
|
|
49
|
+
export function replayActions<
|
|
50
|
+
S extends IGameState = IGameState,
|
|
51
|
+
A extends IAction = IAction,
|
|
52
|
+
>(recording: Recording<S, A>, reducer: GameReducer<S, A>): ReplayResult<S> {
|
|
53
|
+
const snapshots: StateSnapshot<S>[] = [];
|
|
54
|
+
let currentState = recording.initialState;
|
|
55
|
+
|
|
56
|
+
for (let i = 0; i < recording.actions.length; i++) {
|
|
57
|
+
const { action, timestamp } = recording.actions[i];
|
|
58
|
+
currentState = reducer(currentState, action);
|
|
59
|
+
|
|
60
|
+
snapshots.push({
|
|
61
|
+
state: currentState,
|
|
62
|
+
action,
|
|
63
|
+
timestamp,
|
|
64
|
+
index: i,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const endTimestamp =
|
|
69
|
+
recording.endTimestamp ??
|
|
70
|
+
(recording.actions.length > 0
|
|
71
|
+
? recording.actions[recording.actions.length - 1].timestamp
|
|
72
|
+
: recording.startTimestamp);
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
finalState: currentState,
|
|
76
|
+
snapshots,
|
|
77
|
+
duration: endTimestamp - recording.startTimestamp,
|
|
78
|
+
actionCount: recording.actions.length,
|
|
79
|
+
};
|
|
80
|
+
}
|