@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 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
@@ -1,5 +1,6 @@
1
1
  export * from "./types";
2
2
  export * from "./protocol";
3
3
  export * from "./constants";
4
+ export * from "./replay";
4
5
  export * from "./middleware";
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -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"}
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@couch-kit/core",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./types";
2
2
  export * from "./protocol";
3
3
  export * from "./constants";
4
+ export * from "./replay";
4
5
  export * from "./middleware";
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
+ }