volleyballsimtypes 0.0.471 → 0.0.473

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.
@@ -76,6 +76,33 @@ const rally_event_1 = require("./rally-event");
76
76
  const decoded = (0, rally_event_1.transformToSpike)(legacy, roster);
77
77
  (0, globals_1.expect)(decoded.incident).toBeUndefined();
78
78
  });
79
+ (0, globals_1.it)('packs a non-actor blocker incident with the hurt player under h and round-trips it', () => {
80
+ const lead = (0, uuid_1.v4)();
81
+ const helper = (0, uuid_1.v4)();
82
+ const blockRoster = [lead, helper];
83
+ const blockIndex = new Map(blockRoster.map((id, i) => [id, i]));
84
+ const block = service_1.Block.create({
85
+ playerId: lead,
86
+ blockers: [lead, helper],
87
+ score: 48,
88
+ target: 8,
89
+ failure: service_1.BlockFailureEnum.NO_FAILURE,
90
+ type: service_1.BlockTypeEnum.DOUBLE,
91
+ incident: { kind: 'KNOCK', severity: 3, playerId: helper }
92
+ });
93
+ const compact = (0, rally_event_1.transformToCompact)(block, blockIndex);
94
+ (0, globals_1.expect)(compact.i).toBe(13);
95
+ (0, globals_1.expect)(compact.h).toBe(1);
96
+ const decoded = (0, rally_event_1.transformToBlock)(compact, blockRoster);
97
+ (0, globals_1.expect)(decoded.incident).toEqual({ kind: 'KNOCK', severity: 3, playerId: helper });
98
+ });
99
+ (0, globals_1.it)('omits h when the hurt player IS the event actor', () => {
100
+ const compact = (0, rally_event_1.transformToCompact)(makeSpike({ kind: 'INJURY', severity: 2, playerId }), playerIndex);
101
+ (0, globals_1.expect)(compact.i).toBe(2);
102
+ (0, globals_1.expect)('h' in compact).toBe(false);
103
+ const decoded = (0, rally_event_1.transformToSpike)(compact, roster);
104
+ (0, globals_1.expect)(decoded.incident).toEqual({ kind: 'INJURY', severity: 2 });
105
+ });
79
106
  (0, globals_1.it)('rejects an out-of-range or malformed incident at the schema', () => {
80
107
  (0, globals_1.expect)(() => makeSpike({ kind: 'INJURY', severity: 5 })).toThrow(/INVALID_SPIKE/);
81
108
  (0, globals_1.expect)(() => makeSpike({ kind: 'INJURY', severity: 0 })).toThrow(/INVALID_SPIKE/);
@@ -11,6 +11,7 @@ export interface CompactEvent {
11
11
  o?: number;
12
12
  j?: number;
13
13
  i?: number;
14
+ h?: number;
14
15
  }
15
16
  export declare function transformToCompact(evt: RallyEvent, playerIndex: Map<string, number>): CompactEvent;
16
17
  export declare function transformToBlock(event: CompactEvent, roster: string[]): Block;
@@ -15,10 +15,14 @@ function incidentToCompact(incident) {
15
15
  return undefined;
16
16
  return incident.kind === 'KNOCK' ? 10 + incident.severity : incident.severity;
17
17
  }
18
- function incidentFromCompact(i) {
18
+ function incidentFromCompact(i, h, roster) {
19
19
  if (i == null)
20
20
  return undefined;
21
- return i >= 10 ? { kind: 'KNOCK', severity: i - 10 } : { kind: 'INJURY', severity: i };
21
+ const playerId = h != null && roster != null ? roster[h] : undefined;
22
+ return {
23
+ ...(i >= 10 ? { kind: 'KNOCK', severity: i - 10 } : { kind: 'INJURY', severity: i }),
24
+ ...(playerId != null ? { playerId } : {})
25
+ };
22
26
  }
23
27
  function transformToCompact(evt, playerIndex) {
24
28
  const out = {
@@ -31,8 +35,12 @@ function transformToCompact(evt, playerIndex) {
31
35
  out.a = evt.target;
32
36
  out.s = evt.score;
33
37
  const i = incidentToCompact(evt.incident);
34
- if (i != null)
38
+ if (i != null) {
35
39
  out.i = i;
40
+ if (evt.incident?.playerId != null && evt.incident.playerId !== evt.playerId) {
41
+ out.h = playerIndex.get(evt.incident.playerId);
42
+ }
43
+ }
36
44
  if (evt instanceof service_1.Block) {
37
45
  out.b = evt.blockers.map(id => playerIndex.get(id));
38
46
  }
@@ -56,7 +64,7 @@ function transformToBlock(event, roster) {
56
64
  target: event.a,
57
65
  blockers: (event.b ?? []).map(i => roster[i]),
58
66
  score: event.s,
59
- incident: incidentFromCompact(event.i)
67
+ incident: incidentFromCompact(event.i, event.h, roster)
60
68
  });
61
69
  }
62
70
  function transformToLiberoReplacement(event, roster) {
@@ -73,7 +81,7 @@ function transformToReception(event, roster) {
73
81
  playerId: roster[event.p],
74
82
  target: event.a,
75
83
  score: event.s,
76
- incident: incidentFromCompact(event.i)
84
+ incident: incidentFromCompact(event.i, event.h, roster)
77
85
  });
78
86
  }
79
87
  function transformToServe(event, roster) {
@@ -83,7 +91,7 @@ function transformToServe(event, roster) {
83
91
  playerId: roster[event.p],
84
92
  target: event.a,
85
93
  score: event.s,
86
- incident: incidentFromCompact(event.i)
94
+ incident: incidentFromCompact(event.i, event.h, roster)
87
95
  });
88
96
  }
89
97
  function transformToSet(event, roster) {
@@ -93,7 +101,7 @@ function transformToSet(event, roster) {
93
101
  playerId: roster[event.p],
94
102
  target: event.a,
95
103
  score: event.s,
96
- incident: incidentFromCompact(event.i)
104
+ incident: incidentFromCompact(event.i, event.h, roster)
97
105
  });
98
106
  }
99
107
  function transformToSpike(event, roster) {
@@ -103,7 +111,7 @@ function transformToSpike(event, roster) {
103
111
  playerId: roster[event.p],
104
112
  target: event.a,
105
113
  score: event.s,
106
- incident: incidentFromCompact(event.i)
114
+ incident: incidentFromCompact(event.i, event.h, roster)
107
115
  });
108
116
  }
109
117
  function transformToSubstitution(event, roster) {
@@ -4,6 +4,7 @@ import { Trait } from '../player';
4
4
  export interface EventIncident {
5
5
  readonly kind: 'KNOCK' | 'INJURY';
6
6
  readonly severity: number;
7
+ readonly playerId?: string;
7
8
  }
8
9
  export interface InPlayEventOpts extends RallyEventOpts {
9
10
  readonly target: CourtTarget;
@@ -33,6 +33,7 @@ export declare const BlockInputSchema: z.ZodObject<{
33
33
  INJURY: "INJURY";
34
34
  }>;
35
35
  severity: z.ZodNumber;
36
+ playerId: z.ZodOptional<z.ZodUUID>;
36
37
  }, z.core.$strip>>;
37
38
  }, z.core.$strip>;
38
39
  export type BlockInput = z.infer<typeof BlockInputSchema>;
@@ -5,5 +5,6 @@ export declare const EventIncidentSchema: z.ZodObject<{
5
5
  INJURY: "INJURY";
6
6
  }>;
7
7
  severity: z.ZodNumber;
8
+ playerId: z.ZodOptional<z.ZodUUID>;
8
9
  }, z.core.$strip>;
9
10
  export type EventIncidentInput = z.infer<typeof EventIncidentSchema>;
@@ -7,5 +7,8 @@ const zod_1 = require("zod");
7
7
  // InjurySeverityEnum value (1-4).
8
8
  exports.EventIncidentSchema = zod_1.z.object({
9
9
  kind: zod_1.z.enum(['KNOCK', 'INJURY']),
10
- severity: zod_1.z.number().int().min(1).max(4)
10
+ severity: zod_1.z.number().int().min(1).max(4),
11
+ // Who got hurt, ONLY when it is not the event's actor (a secondary blocker on a multi-player block);
12
+ // absent = the event's own playerId.
13
+ playerId: zod_1.z.uuid().optional()
11
14
  }).refine(v => v.kind !== 'KNOCK' || v.severity <= 3, { message: 'INVALID_KNOCK_TIER' });
@@ -32,6 +32,7 @@ export declare const ReceptionInputSchema: z.ZodObject<{
32
32
  INJURY: "INJURY";
33
33
  }>;
34
34
  severity: z.ZodNumber;
35
+ playerId: z.ZodOptional<z.ZodUUID>;
35
36
  }, z.core.$strip>>;
36
37
  }, z.core.$strip>;
37
38
  export type ReceptionInput = z.infer<typeof ReceptionInputSchema>;
@@ -32,6 +32,7 @@ export declare const ServeInputSchema: z.ZodObject<{
32
32
  INJURY: "INJURY";
33
33
  }>;
34
34
  severity: z.ZodNumber;
35
+ playerId: z.ZodOptional<z.ZodUUID>;
35
36
  }, z.core.$strip>>;
36
37
  }, z.core.$strip>;
37
38
  export type ServeInput = z.infer<typeof ServeInputSchema>;
@@ -32,6 +32,7 @@ export declare const SetInputSchema: z.ZodObject<{
32
32
  INJURY: "INJURY";
33
33
  }>;
34
34
  severity: z.ZodNumber;
35
+ playerId: z.ZodOptional<z.ZodUUID>;
35
36
  }, z.core.$strip>>;
36
37
  }, z.core.$strip>;
37
38
  export type SetInput = z.infer<typeof SetInputSchema>;
@@ -32,6 +32,7 @@ export declare const SpikeInputSchema: z.ZodObject<{
32
32
  INJURY: "INJURY";
33
33
  }>;
34
34
  severity: z.ZodNumber;
35
+ playerId: z.ZodOptional<z.ZodUUID>;
35
36
  }, z.core.$strip>>;
36
37
  }, z.core.$strip>;
37
38
  export type SpikeInput = z.infer<typeof SpikeInputSchema>;
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect } from '@jest/globals';
2
2
  import { v4 as uuidv4 } from 'uuid';
3
- import { EventTypeEnum, Serve, ServeFailureEnum, ServeTypeEnum, Spike, SpikeFailureEnum, SpikeTypeEnum, Substitution } from '../../service';
4
- import { transformToCompact, transformToServe, transformToSpike, transformToSubstitution } from './rally-event';
3
+ import { Block, BlockFailureEnum, BlockTypeEnum, EventTypeEnum, Serve, ServeFailureEnum, ServeTypeEnum, Spike, SpikeFailureEnum, SpikeTypeEnum, Substitution } from '../../service';
4
+ import { transformToBlock, transformToCompact, transformToServe, transformToSpike, transformToSubstitution } from './rally-event';
5
5
  describe('rally-event compact round trip — injury substitution marker', () => {
6
6
  const playerIn = uuidv4();
7
7
  const playerOut = uuidv4();
@@ -74,6 +74,33 @@ describe('rally-event compact round trip — incident marker on the causing even
74
74
  const decoded = transformToSpike(legacy, roster);
75
75
  expect(decoded.incident).toBeUndefined();
76
76
  });
77
+ it('packs a non-actor blocker incident with the hurt player under h and round-trips it', () => {
78
+ const lead = uuidv4();
79
+ const helper = uuidv4();
80
+ const blockRoster = [lead, helper];
81
+ const blockIndex = new Map(blockRoster.map((id, i) => [id, i]));
82
+ const block = Block.create({
83
+ playerId: lead,
84
+ blockers: [lead, helper],
85
+ score: 48,
86
+ target: 8,
87
+ failure: BlockFailureEnum.NO_FAILURE,
88
+ type: BlockTypeEnum.DOUBLE,
89
+ incident: { kind: 'KNOCK', severity: 3, playerId: helper }
90
+ });
91
+ const compact = transformToCompact(block, blockIndex);
92
+ expect(compact.i).toBe(13);
93
+ expect(compact.h).toBe(1);
94
+ const decoded = transformToBlock(compact, blockRoster);
95
+ expect(decoded.incident).toEqual({ kind: 'KNOCK', severity: 3, playerId: helper });
96
+ });
97
+ it('omits h when the hurt player IS the event actor', () => {
98
+ const compact = transformToCompact(makeSpike({ kind: 'INJURY', severity: 2, playerId }), playerIndex);
99
+ expect(compact.i).toBe(2);
100
+ expect('h' in compact).toBe(false);
101
+ const decoded = transformToSpike(compact, roster);
102
+ expect(decoded.incident).toEqual({ kind: 'INJURY', severity: 2 });
103
+ });
77
104
  it('rejects an out-of-range or malformed incident at the schema', () => {
78
105
  expect(() => makeSpike({ kind: 'INJURY', severity: 5 })).toThrow(/INVALID_SPIKE/);
79
106
  expect(() => makeSpike({ kind: 'INJURY', severity: 0 })).toThrow(/INVALID_SPIKE/);
@@ -11,6 +11,7 @@ export interface CompactEvent {
11
11
  o?: number;
12
12
  j?: number;
13
13
  i?: number;
14
+ h?: number;
14
15
  }
15
16
  export declare function transformToCompact(evt: RallyEvent, playerIndex: Map<string, number>): CompactEvent;
16
17
  export declare function transformToBlock(event: CompactEvent, roster: string[]): Block;
@@ -5,10 +5,14 @@ function incidentToCompact(incident) {
5
5
  return undefined;
6
6
  return incident.kind === 'KNOCK' ? 10 + incident.severity : incident.severity;
7
7
  }
8
- function incidentFromCompact(i) {
8
+ function incidentFromCompact(i, h, roster) {
9
9
  if (i == null)
10
10
  return undefined;
11
- return i >= 10 ? { kind: 'KNOCK', severity: i - 10 } : { kind: 'INJURY', severity: i };
11
+ const playerId = h != null && roster != null ? roster[h] : undefined;
12
+ return {
13
+ ...(i >= 10 ? { kind: 'KNOCK', severity: i - 10 } : { kind: 'INJURY', severity: i }),
14
+ ...(playerId != null ? { playerId } : {})
15
+ };
12
16
  }
13
17
  export function transformToCompact(evt, playerIndex) {
14
18
  const out = {
@@ -21,8 +25,12 @@ export function transformToCompact(evt, playerIndex) {
21
25
  out.a = evt.target;
22
26
  out.s = evt.score;
23
27
  const i = incidentToCompact(evt.incident);
24
- if (i != null)
28
+ if (i != null) {
25
29
  out.i = i;
30
+ if (evt.incident?.playerId != null && evt.incident.playerId !== evt.playerId) {
31
+ out.h = playerIndex.get(evt.incident.playerId);
32
+ }
33
+ }
26
34
  if (evt instanceof Block) {
27
35
  out.b = evt.blockers.map(id => playerIndex.get(id));
28
36
  }
@@ -46,7 +54,7 @@ export function transformToBlock(event, roster) {
46
54
  target: event.a,
47
55
  blockers: (event.b ?? []).map(i => roster[i]),
48
56
  score: event.s,
49
- incident: incidentFromCompact(event.i)
57
+ incident: incidentFromCompact(event.i, event.h, roster)
50
58
  });
51
59
  }
52
60
  export function transformToLiberoReplacement(event, roster) {
@@ -63,7 +71,7 @@ export function transformToReception(event, roster) {
63
71
  playerId: roster[event.p],
64
72
  target: event.a,
65
73
  score: event.s,
66
- incident: incidentFromCompact(event.i)
74
+ incident: incidentFromCompact(event.i, event.h, roster)
67
75
  });
68
76
  }
69
77
  export function transformToServe(event, roster) {
@@ -73,7 +81,7 @@ export function transformToServe(event, roster) {
73
81
  playerId: roster[event.p],
74
82
  target: event.a,
75
83
  score: event.s,
76
- incident: incidentFromCompact(event.i)
84
+ incident: incidentFromCompact(event.i, event.h, roster)
77
85
  });
78
86
  }
79
87
  export function transformToSet(event, roster) {
@@ -83,7 +91,7 @@ export function transformToSet(event, roster) {
83
91
  playerId: roster[event.p],
84
92
  target: event.a,
85
93
  score: event.s,
86
- incident: incidentFromCompact(event.i)
94
+ incident: incidentFromCompact(event.i, event.h, roster)
87
95
  });
88
96
  }
89
97
  export function transformToSpike(event, roster) {
@@ -93,7 +101,7 @@ export function transformToSpike(event, roster) {
93
101
  playerId: roster[event.p],
94
102
  target: event.a,
95
103
  score: event.s,
96
- incident: incidentFromCompact(event.i)
104
+ incident: incidentFromCompact(event.i, event.h, roster)
97
105
  });
98
106
  }
99
107
  export function transformToSubstitution(event, roster) {
@@ -4,6 +4,7 @@ import { Trait } from '../player';
4
4
  export interface EventIncident {
5
5
  readonly kind: 'KNOCK' | 'INJURY';
6
6
  readonly severity: number;
7
+ readonly playerId?: string;
7
8
  }
8
9
  export interface InPlayEventOpts extends RallyEventOpts {
9
10
  readonly target: CourtTarget;
@@ -33,6 +33,7 @@ export declare const BlockInputSchema: z.ZodObject<{
33
33
  INJURY: "INJURY";
34
34
  }>;
35
35
  severity: z.ZodNumber;
36
+ playerId: z.ZodOptional<z.ZodUUID>;
36
37
  }, z.core.$strip>>;
37
38
  }, z.core.$strip>;
38
39
  export type BlockInput = z.infer<typeof BlockInputSchema>;
@@ -5,5 +5,6 @@ export declare const EventIncidentSchema: z.ZodObject<{
5
5
  INJURY: "INJURY";
6
6
  }>;
7
7
  severity: z.ZodNumber;
8
+ playerId: z.ZodOptional<z.ZodUUID>;
8
9
  }, z.core.$strip>;
9
10
  export type EventIncidentInput = z.infer<typeof EventIncidentSchema>;
@@ -4,5 +4,8 @@ import { z } from 'zod';
4
4
  // InjurySeverityEnum value (1-4).
5
5
  export const EventIncidentSchema = z.object({
6
6
  kind: z.enum(['KNOCK', 'INJURY']),
7
- severity: z.number().int().min(1).max(4)
7
+ severity: z.number().int().min(1).max(4),
8
+ // Who got hurt, ONLY when it is not the event's actor (a secondary blocker on a multi-player block);
9
+ // absent = the event's own playerId.
10
+ playerId: z.uuid().optional()
8
11
  }).refine(v => v.kind !== 'KNOCK' || v.severity <= 3, { message: 'INVALID_KNOCK_TIER' });
@@ -32,6 +32,7 @@ export declare const ReceptionInputSchema: z.ZodObject<{
32
32
  INJURY: "INJURY";
33
33
  }>;
34
34
  severity: z.ZodNumber;
35
+ playerId: z.ZodOptional<z.ZodUUID>;
35
36
  }, z.core.$strip>>;
36
37
  }, z.core.$strip>;
37
38
  export type ReceptionInput = z.infer<typeof ReceptionInputSchema>;
@@ -32,6 +32,7 @@ export declare const ServeInputSchema: z.ZodObject<{
32
32
  INJURY: "INJURY";
33
33
  }>;
34
34
  severity: z.ZodNumber;
35
+ playerId: z.ZodOptional<z.ZodUUID>;
35
36
  }, z.core.$strip>>;
36
37
  }, z.core.$strip>;
37
38
  export type ServeInput = z.infer<typeof ServeInputSchema>;
@@ -32,6 +32,7 @@ export declare const SetInputSchema: z.ZodObject<{
32
32
  INJURY: "INJURY";
33
33
  }>;
34
34
  severity: z.ZodNumber;
35
+ playerId: z.ZodOptional<z.ZodUUID>;
35
36
  }, z.core.$strip>>;
36
37
  }, z.core.$strip>;
37
38
  export type SetInput = z.infer<typeof SetInputSchema>;
@@ -32,6 +32,7 @@ export declare const SpikeInputSchema: z.ZodObject<{
32
32
  INJURY: "INJURY";
33
33
  }>;
34
34
  severity: z.ZodNumber;
35
+ playerId: z.ZodOptional<z.ZodUUID>;
35
36
  }, z.core.$strip>>;
36
37
  }, z.core.$strip>;
37
38
  export type SpikeInput = z.infer<typeof SpikeInputSchema>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.471",
3
+ "version": "0.0.473",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",