@couch-kit/core 0.7.0 → 0.8.1

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,17 @@
1
1
  # @couch-kit/core
2
2
 
3
+ ## 0.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#27](https://github.com/faluciano/react-native-couch-kit/pull/27) [`4976357`](https://github.com/faluciano/react-native-couch-kit/commit/49763573df502e394d5591b73000f48ee711d7a8) Thanks [@faluciano](https://github.com/faluciano)! - Fix WebSocket connection failure caused by path mismatch: the client connected to `ws://host:8082` (root path `/`) while the server only accepted upgrades on `/ws`. Added shared `DEFAULT_WS_PATH` constant to `@couch-kit/core` and use it in both client URL construction and server handler registration.
8
+
9
+ ## 0.8.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#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.
14
+
3
15
  ## 0.7.0
4
16
 
5
17
  ### Minor Changes
package/dist/index.js CHANGED
@@ -161,6 +161,7 @@ var MessageTypes = {
161
161
  // src/constants.ts
162
162
  var DEFAULT_HTTP_PORT = 8080;
163
163
  var DEFAULT_WS_PORT_OFFSET = 2;
164
+ var DEFAULT_WS_PATH = "/ws";
164
165
  var MAX_FRAME_SIZE = 1024 * 1024;
165
166
  var DEFAULT_MAX_RETRIES = 5;
166
167
  var DEFAULT_BASE_DELAY = 1000;
@@ -200,8 +201,31 @@ function toErrorMessage(error) {
200
201
  return error.message;
201
202
  return String(error);
202
203
  }
204
+ // src/replay.ts
205
+ function replayActions(recording, reducer) {
206
+ const snapshots = [];
207
+ let currentState = recording.initialState;
208
+ for (let i = 0;i < recording.actions.length; i++) {
209
+ const { action, timestamp } = recording.actions[i];
210
+ currentState = reducer(currentState, action);
211
+ snapshots.push({
212
+ state: currentState,
213
+ action,
214
+ timestamp,
215
+ index: i
216
+ });
217
+ }
218
+ const endTimestamp = recording.endTimestamp ?? (recording.actions.length > 0 ? recording.actions[recording.actions.length - 1].timestamp : recording.startTimestamp);
219
+ return {
220
+ finalState: currentState,
221
+ snapshots,
222
+ duration: endTimestamp - recording.startTimestamp,
223
+ actionCount: recording.actions.length
224
+ };
225
+ }
203
226
  export {
204
227
  toErrorMessage,
228
+ replayActions,
205
229
  isValidSecret,
206
230
  generateId,
207
231
  derivePlayerIdLegacy,
@@ -217,6 +241,7 @@ export {
217
241
  KEEPALIVE_INTERVAL,
218
242
  InternalActionTypes,
219
243
  DEFAULT_WS_PORT_OFFSET,
244
+ DEFAULT_WS_PATH,
220
245
  DEFAULT_SYNC_INTERVAL,
221
246
  DEFAULT_MAX_RETRIES,
222
247
  DEFAULT_MAX_DELAY,
@@ -3,6 +3,8 @@
3
3
  export declare const DEFAULT_HTTP_PORT = 8080;
4
4
  /** Default WebSocket port offset from the HTTP port (skips Metro on +1). */
5
5
  export declare const DEFAULT_WS_PORT_OFFSET = 2;
6
+ /** Default WebSocket endpoint path on the host server. */
7
+ export declare const DEFAULT_WS_PATH = "/ws";
6
8
  /** @deprecated Not used by Couch Kit internals. Will be removed in the next major version. */
7
9
  export declare const MAX_FRAME_SIZE: number;
8
10
  /** Default maximum reconnection attempts for the client. */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAEtC,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,8FAA8F;AAC9F,eAAO,MAAM,cAAc,QAAc,CAAC;AAE1C,4DAA4D;AAC5D,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,oEAAoE;AACpE,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,+EAA+E;AAC/E,eAAO,MAAM,0BAA0B,QAAgB,CAAC;AAExD,8FAA8F;AAC9F,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAExC,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAwBnC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOpE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGrD"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAEtC,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,0DAA0D;AAC1D,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,8FAA8F;AAC9F,eAAO,MAAM,cAAc,QAAc,CAAC;AAE1C,4DAA4D;AAC5D,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,oEAAoE;AACpE,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,+EAA+E;AAC/E,eAAO,MAAM,0BAA0B,QAAgB,CAAC;AAExD,8FAA8F;AAC9F,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAExC,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAwBnC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOpE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGrD"}
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.1",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
package/src/constants.ts CHANGED
@@ -6,6 +6,9 @@ export const DEFAULT_HTTP_PORT = 8080;
6
6
  /** Default WebSocket port offset from the HTTP port (skips Metro on +1). */
7
7
  export const DEFAULT_WS_PORT_OFFSET = 2;
8
8
 
9
+ /** Default WebSocket endpoint path on the host server. */
10
+ export const DEFAULT_WS_PATH = "/ws";
11
+
9
12
  /** @deprecated Not used by Couch Kit internals. Will be removed in the next major version. */
10
13
  export const MAX_FRAME_SIZE = 1024 * 1024;
11
14
 
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
+ }