@dreamboard-games/sdk 0.4.0-alpha.0 → 0.4.0-alpha.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.
Files changed (62) hide show
  1. package/README.md +8 -1
  2. package/REFERENCE.md +488 -108
  3. package/dist/attributes-BrZtP9az.d.ts +53 -0
  4. package/dist/browser-interaction.d.ts +44 -42
  5. package/dist/browser-interaction.js +2 -1
  6. package/dist/{chunk-4G7552LO.js → chunk-3K362ZKR.js} +17 -12
  7. package/dist/chunk-3K362ZKR.js.map +1 -0
  8. package/dist/{chunk-U5KBV2BA.js → chunk-7LZZEI25.js} +444 -223
  9. package/dist/chunk-7LZZEI25.js.map +1 -0
  10. package/dist/{chunk-Q5O7GPVY.js → chunk-7W6TQO3X.js} +18 -10
  11. package/dist/chunk-7W6TQO3X.js.map +1 -0
  12. package/dist/chunk-AEUXCFGM.js +124 -0
  13. package/dist/chunk-AEUXCFGM.js.map +1 -0
  14. package/dist/{chunk-P7F4L2FF.js → chunk-CZMFAS3E.js} +327 -248
  15. package/dist/chunk-CZMFAS3E.js.map +1 -0
  16. package/dist/{chunk-MNKDSGIA.js → chunk-IUGKW2GS.js} +2 -2
  17. package/dist/{chunk-MNKDSGIA.js.map → chunk-IUGKW2GS.js.map} +1 -1
  18. package/dist/{chunk-QLG6VEMW.js → chunk-MALRKLRR.js} +19 -11
  19. package/dist/chunk-MALRKLRR.js.map +1 -0
  20. package/dist/{chunk-2LDZ5C3T.js → chunk-XJYUSD5F.js} +2 -2
  21. package/dist/{chunk-NBAEEHAU.js → chunk-XXBSIPJX.js} +5952 -5364
  22. package/dist/chunk-XXBSIPJX.js.map +1 -0
  23. package/dist/codegen.d.ts +3 -1
  24. package/dist/codegen.js +1 -1
  25. package/dist/{components-DaIqi9QM.d.ts → components-Dqr_LuZJ.d.ts} +1 -65
  26. package/dist/index.js +1 -1
  27. package/dist/package-set.d.ts +2 -2
  28. package/dist/package-set.js +1 -1
  29. package/dist/reducer/advanced.d.ts +2 -2
  30. package/dist/reducer/advanced.js +1 -1
  31. package/dist/reducer-contract.js +1 -1
  32. package/dist/reducer.d.ts +7 -7
  33. package/dist/reducer.js +190 -183
  34. package/dist/reducer.js.map +1 -1
  35. package/dist/runtime/primitives.d.ts +4 -3
  36. package/dist/runtime/primitives.js +5 -4
  37. package/dist/runtime/workspace-contract.d.ts +10 -69
  38. package/dist/runtime/workspace-contract.js +6 -5
  39. package/dist/runtime-json-CQ9QbLZ5.d.ts +5 -0
  40. package/dist/runtime.d.ts +70 -5
  41. package/dist/runtime.js +483 -129
  42. package/dist/runtime.js.map +1 -1
  43. package/dist/testing.d.ts +509 -2
  44. package/dist/testing.js +481 -1
  45. package/dist/testing.js.map +1 -1
  46. package/dist/{attributes-BeRyboMS.d.ts → types-BqzHkNMA.d.ts} +1 -51
  47. package/dist/types.d.ts +4 -2
  48. package/dist/ui/components.d.ts +1 -1
  49. package/dist/ui/components.js +1 -1
  50. package/dist/ui/plugin-styles.css +1 -1
  51. package/dist/{ui-contract-BUC6iS3s.d.ts → ui-contract-W2-kxObe.d.ts} +2 -1
  52. package/dist/ui.d.ts +3 -7
  53. package/dist/ui.js +2 -2
  54. package/dist/{views-B0hlW6IT.d.ts → views-fn2RuXOx.d.ts} +59 -44
  55. package/package.json +31 -13
  56. package/dist/chunk-4G7552LO.js.map +0 -1
  57. package/dist/chunk-NBAEEHAU.js.map +0 -1
  58. package/dist/chunk-P7F4L2FF.js.map +0 -1
  59. package/dist/chunk-Q5O7GPVY.js.map +0 -1
  60. package/dist/chunk-QLG6VEMW.js.map +0 -1
  61. package/dist/chunk-U5KBV2BA.js.map +0 -1
  62. /package/dist/{chunk-2LDZ5C3T.js.map → chunk-XJYUSD5F.js.map} +0 -0
package/dist/testing.js CHANGED
@@ -2,6 +2,14 @@ import {
2
2
  StaleContractArtifactError,
3
3
  isStaleContractArtifactError
4
4
  } from "./chunk-3OZMHZK3.js";
5
+ import {
6
+ BROWSER_INTERACTION_ACTUATOR_KINDS,
7
+ DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,
8
+ browserInteractionEffectSchema
9
+ } from "./chunk-MALRKLRR.js";
10
+ import {
11
+ RuntimeJsonSchema
12
+ } from "./chunk-AEUXCFGM.js";
5
13
  import "./chunk-PZ5AY32C.js";
6
14
 
7
15
  // src/testing/definitions.ts
@@ -666,12 +674,484 @@ function createTestRuntime(options) {
666
674
  setControllingPlayer
667
675
  };
668
676
  }
677
+
678
+ // src/testing/ui-fixture/canonical.ts
679
+ import { createHash } from "crypto";
680
+ var sha256DigestPattern = /^sha256:[a-f0-9]{64}$/;
681
+ function isSha256Digest(value) {
682
+ return sha256DigestPattern.test(value);
683
+ }
684
+ function canonicalizeUIFixtureJson(value) {
685
+ if (value === null) {
686
+ return null;
687
+ }
688
+ switch (typeof value) {
689
+ case "boolean":
690
+ case "string":
691
+ return value;
692
+ case "number":
693
+ if (Number.isFinite(value)) {
694
+ return value;
695
+ }
696
+ break;
697
+ case "object": {
698
+ if (Array.isArray(value)) {
699
+ return value.map((item) => canonicalizeUIFixtureJson(item));
700
+ }
701
+ if (Object.getPrototypeOf(value) !== Object.prototype) {
702
+ break;
703
+ }
704
+ const entries = Object.entries(value);
705
+ return Object.fromEntries(
706
+ entries.filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => [key, canonicalizeUIFixtureJson(item)])
707
+ );
708
+ }
709
+ }
710
+ throw new Error(
711
+ `UI fixture values must be deterministic JSON. Received ${typeof value}.`
712
+ );
713
+ }
714
+ function canonicalUIFixtureJson(value) {
715
+ return JSON.stringify(canonicalizeUIFixtureJson(value));
716
+ }
717
+ function digestUIFixtureJson(value) {
718
+ return sha256(canonicalUIFixtureJson(value));
719
+ }
720
+ function digestUIFixtureRequest(request) {
721
+ return digestUIFixtureJson({
722
+ digestVersion: "ui-replay-request@1",
723
+ request
724
+ });
725
+ }
726
+ function canonicalizeUIScenarioFixture(fixture) {
727
+ return canonicalizeUIFixtureJson({
728
+ ...fixture,
729
+ tags: [...fixture.tags].sort(),
730
+ environment: {
731
+ ...fixture.environment,
732
+ viewportTags: [...fixture.environment.viewportTags].sort()
733
+ }
734
+ });
735
+ }
736
+ function serializeUIScenarioFixture(fixture) {
737
+ return `${JSON.stringify(canonicalizeUIScenarioFixture(fixture), null, 2)}
738
+ `;
739
+ }
740
+ function digestUIScenarioFixture(fixture) {
741
+ return sha256(serializeUIScenarioFixture(fixture));
742
+ }
743
+ function sha256(value) {
744
+ return `sha256:${createHash("sha256").update(value).digest("hex")}`;
745
+ }
746
+
747
+ // src/testing/ui-fixture/schema.ts
748
+ import { z } from "zod";
749
+ var UI_SCENARIO_FIXTURE_SCHEMA_VERSION = 1;
750
+ var UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION = 1;
751
+ var UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR = 2;
752
+ var digestSchema = z.string().refine(isSha256Digest, {
753
+ message: "Expected a sha256:<64 lowercase hex> digest."
754
+ });
755
+ var nonEmptyStringSchema = z.string().min(1);
756
+ var jsonSchema = RuntimeJsonSchema;
757
+ var environmentSchema = z.object({
758
+ clockIso: nonEmptyStringSchema,
759
+ randomSeed: nonEmptyStringSchema,
760
+ locale: z.literal("en-US"),
761
+ timezone: z.literal("UTC"),
762
+ viewportTags: z.array(z.enum(["desktop", "tablet", "phone", "touch"]))
763
+ }).strict();
764
+ var pluginSessionSchema = z.object({
765
+ sessionId: nonEmptyStringSchema,
766
+ controllablePlayerIds: z.array(nonEmptyStringSchema),
767
+ controllingPlayerId: nonEmptyStringSchema.nullable(),
768
+ userId: nonEmptyStringSchema.nullable()
769
+ }).catchall(jsonSchema);
770
+ var gameplaySnapshotSchema = z.object({
771
+ currentPhase: nonEmptyStringSchema.nullable(),
772
+ currentStage: nonEmptyStringSchema.nullable(),
773
+ activePlayers: z.array(nonEmptyStringSchema),
774
+ simultaneousPhase: jsonSchema.nullable().optional(),
775
+ availableInteractions: z.array(jsonSchema),
776
+ zones: z.record(z.string(), jsonSchema)
777
+ }).catchall(jsonSchema);
778
+ var uiFixturePluginStateSnapshotSchema = z.object({
779
+ view: jsonSchema.nullable(),
780
+ gameplay: gameplaySnapshotSchema,
781
+ lobby: jsonSchema.nullable(),
782
+ notifications: z.array(jsonSchema),
783
+ session: pluginSessionSchema,
784
+ history: jsonSchema.nullable(),
785
+ syncId: z.number().int().nonnegative()
786
+ }).strict();
787
+ var uiFixtureFrameSchema = z.object({
788
+ id: nonEmptyStringSchema,
789
+ snapshot: uiFixturePluginStateSnapshotSchema,
790
+ projectionDigest: digestSchema
791
+ }).strict();
792
+ var uiFixtureTransportExchangeSchema = z.object({
793
+ id: nonEmptyStringSchema,
794
+ fromFrameId: nonEmptyStringSchema,
795
+ operation: z.enum(["validate", "submit", "refresh"]),
796
+ requestDigest: digestSchema,
797
+ response: z.union([
798
+ z.object({
799
+ kind: z.literal("accepted"),
800
+ nextFrameId: nonEmptyStringSchema
801
+ }).strict(),
802
+ z.object({
803
+ kind: z.literal("rejected"),
804
+ diagnostics: z.array(
805
+ z.object({
806
+ code: nonEmptyStringSchema,
807
+ message: nonEmptyStringSchema
808
+ }).strict()
809
+ )
810
+ }).strict()
811
+ ])
812
+ }).strict();
813
+ var browserInteractionIntentRequestSchema = z.object({
814
+ surface: nonEmptyStringSchema,
815
+ scopeId: nonEmptyStringSchema.optional(),
816
+ interactionKey: nonEmptyStringSchema.optional(),
817
+ interactionId: nonEmptyStringSchema.optional(),
818
+ intent: nonEmptyStringSchema,
819
+ inputKey: nonEmptyStringSchema.optional(),
820
+ candidateValue: jsonSchema.optional(),
821
+ candidateValueKey: nonEmptyStringSchema.optional(),
822
+ actuatorKind: z.enum(BROWSER_INTERACTION_ACTUATOR_KINDS).optional(),
823
+ allowDisabled: z.boolean().optional()
824
+ }).strict();
825
+ var browserInteractionEffectRequestSchema = z.object({
826
+ surface: nonEmptyStringSchema,
827
+ scopeId: nonEmptyStringSchema.optional(),
828
+ interactionKey: nonEmptyStringSchema.optional(),
829
+ interactionId: nonEmptyStringSchema.optional(),
830
+ effect: browserInteractionEffectSchema,
831
+ allowDisabled: z.boolean().optional()
832
+ }).strict();
833
+ var uiReplayRequestSchema = z.union([
834
+ browserInteractionIntentRequestSchema,
835
+ browserInteractionEffectRequestSchema
836
+ ]);
837
+ var uiReplayExecutionSchema = z.union([
838
+ z.object({
839
+ kind: z.literal("activate")
840
+ }).strict(),
841
+ z.object({
842
+ kind: z.literal("fill"),
843
+ value: z.string()
844
+ }).strict(),
845
+ z.object({
846
+ kind: z.literal("drag"),
847
+ target: browserInteractionEffectRequestSchema
848
+ }).strict()
849
+ ]);
850
+ var uiStepExpectationSchema = z.object({
851
+ frameId: nonEmptyStringSchema.optional(),
852
+ projectionDigest: digestSchema.optional(),
853
+ semanticDigest: digestSchema.optional(),
854
+ draftDigest: digestSchema.optional(),
855
+ submissionDigest: digestSchema.optional(),
856
+ focusedInteractionKey: nonEmptyStringSchema.optional(),
857
+ visibleInteractionKeys: z.array(nonEmptyStringSchema).optional()
858
+ }).strict();
859
+ var uiResolvedReplayIdentitySchema = z.object({
860
+ stepId: nonEmptyStringSchema,
861
+ surface: nonEmptyStringSchema,
862
+ scopeId: nonEmptyStringSchema,
863
+ interactionKey: nonEmptyStringSchema,
864
+ interactionId: nonEmptyStringSchema,
865
+ actuatorId: nonEmptyStringSchema,
866
+ descriptorDigest: digestSchema.optional(),
867
+ draftDigest: digestSchema.optional()
868
+ }).strict();
869
+ var portableSemanticReplayStepSchema = z.object({
870
+ stepId: nonEmptyStringSchema,
871
+ requestDigest: digestSchema,
872
+ resolve: uiReplayRequestSchema,
873
+ execute: uiReplayExecutionSchema,
874
+ expectedIdentity: uiResolvedReplayIdentitySchema.optional(),
875
+ expect: uiStepExpectationSchema
876
+ }).strict();
877
+ var uiScenarioReplayStepSchema = z.union([
878
+ portableSemanticReplayStepSchema,
879
+ z.object({
880
+ stepId: nonEmptyStringSchema,
881
+ kind: z.literal("assert"),
882
+ expect: uiStepExpectationSchema
883
+ }).strict()
884
+ ]);
885
+ var uiScenarioFixtureSchema = z.object({
886
+ schemaVersion: z.literal(UI_SCENARIO_FIXTURE_SCHEMA_VERSION),
887
+ browserInteractionProtocol: z.literal(
888
+ DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION
889
+ ),
890
+ id: nonEmptyStringSchema,
891
+ title: nonEmptyStringSchema,
892
+ gameId: nonEmptyStringSchema,
893
+ tags: z.array(nonEmptyStringSchema),
894
+ source: z.object({
895
+ scenarioId: nonEmptyStringSchema,
896
+ reducerFingerprint: nonEmptyStringSchema,
897
+ uiContractFingerprint: nonEmptyStringSchema,
898
+ renderModule: nonEmptyStringSchema,
899
+ renderModuleDigest: digestSchema,
900
+ sourceDigest: digestSchema
901
+ }).strict(),
902
+ viewer: z.object({
903
+ seatId: nonEmptyStringSchema,
904
+ playerId: nonEmptyStringSchema.optional()
905
+ }).strict(),
906
+ environment: environmentSchema,
907
+ frames: z.array(uiFixtureFrameSchema).min(1),
908
+ transport: z.array(uiFixtureTransportExchangeSchema),
909
+ replay: z.array(uiScenarioReplayStepSchema),
910
+ expected: z.object({
911
+ initialProjectionDigest: digestSchema,
912
+ finalProjectionDigest: digestSchema,
913
+ finalSemanticDigest: digestSchema,
914
+ submissionDigest: digestSchema
915
+ }).strict()
916
+ }).strict();
917
+ var uiScenarioFixtureBundleIndexSchema = z.object({
918
+ schemaVersion: z.literal(UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION),
919
+ bundleId: nonEmptyStringSchema,
920
+ sdkCommit: nonEmptyStringSchema,
921
+ browserInteractionProtocol: z.literal(
922
+ DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION
923
+ ),
924
+ fixtures: z.array(
925
+ z.object({
926
+ id: nonEmptyStringSchema,
927
+ file: nonEmptyStringSchema,
928
+ sha256: digestSchema,
929
+ renderModule: nonEmptyStringSchema,
930
+ renderModuleSha256: digestSchema,
931
+ components: z.array(nonEmptyStringSchema),
932
+ capabilities: z.array(nonEmptyStringSchema)
933
+ }).strict()
934
+ )
935
+ }).strict();
936
+ function parseUIScenarioFixture(value) {
937
+ const fixture = uiScenarioFixtureSchema.parse(
938
+ value
939
+ );
940
+ validateUIScenarioFixtureReferences(fixture);
941
+ return fixture;
942
+ }
943
+ function parseUIScenarioFixtureBundleIndex(value) {
944
+ const bundle = uiScenarioFixtureBundleIndexSchema.parse(value);
945
+ assertSupportedBrowserInteractionProtocol(bundle.browserInteractionProtocol);
946
+ const ids = /* @__PURE__ */ new Set();
947
+ for (const entry of bundle.fixtures) {
948
+ if (ids.has(entry.id)) {
949
+ throw new Error(`Duplicate fixture id '${entry.id}' in bundle index.`);
950
+ }
951
+ ids.add(entry.id);
952
+ }
953
+ return bundle;
954
+ }
955
+ function assertSupportedBrowserInteractionProtocol(version) {
956
+ const major = Number(version.split(".")[0]);
957
+ if (major !== UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR) {
958
+ throw new Error(
959
+ `Unsupported browser-interaction protocol '${version}'. Expected major ${UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR}.`
960
+ );
961
+ }
962
+ }
963
+ function validateUIScenarioFixtureReferences(fixture) {
964
+ assertSupportedBrowserInteractionProtocol(fixture.browserInteractionProtocol);
965
+ const frameIds = /* @__PURE__ */ new Set();
966
+ for (const frame of fixture.frames) {
967
+ if (frameIds.has(frame.id)) {
968
+ throw new Error(`Duplicate fixture frame id '${frame.id}'.`);
969
+ }
970
+ frameIds.add(frame.id);
971
+ }
972
+ for (const exchange of fixture.transport) {
973
+ if (!frameIds.has(exchange.fromFrameId)) {
974
+ throw new Error(
975
+ `Transport exchange '${exchange.id}' references missing fromFrameId '${exchange.fromFrameId}'.`
976
+ );
977
+ }
978
+ if (exchange.response.kind === "accepted" && !frameIds.has(exchange.response.nextFrameId)) {
979
+ throw new Error(
980
+ `Transport exchange '${exchange.id}' references missing nextFrameId '${exchange.response.nextFrameId}'.`
981
+ );
982
+ }
983
+ }
984
+ for (const step of fixture.replay) {
985
+ if ("resolve" in step) {
986
+ const actualDigest = digestUIFixtureRequest(
987
+ step.resolve
988
+ );
989
+ if (step.requestDigest !== actualDigest) {
990
+ throw new Error(
991
+ `Replay step '${step.stepId}' requestDigest ${step.requestDigest} does not match ${actualDigest}.`
992
+ );
993
+ }
994
+ }
995
+ const expectedFrameId = step.expect.frameId;
996
+ if (expectedFrameId && !frameIds.has(expectedFrameId)) {
997
+ throw new Error(
998
+ `Replay step '${step.stepId}' expects missing frameId '${expectedFrameId}'.`
999
+ );
1000
+ }
1001
+ }
1002
+ }
1003
+
1004
+ // src/testing/ui-fixture/compiler.ts
1005
+ function compileUIScenarioFixture(options) {
1006
+ const firstFrame = options.frames[0];
1007
+ const finalFrame = options.frames[options.frames.length - 1];
1008
+ if (!firstFrame || !finalFrame) {
1009
+ throw new Error("compileUIScenarioFixture requires at least one frame.");
1010
+ }
1011
+ const replay = options.replay ?? [];
1012
+ const submissionDigest = options.expected?.submissionDigest ?? digestUIFixtureJson({
1013
+ digestVersion: "ui-submission@1",
1014
+ fixtureId: options.id,
1015
+ replay: replay.map(
1016
+ (step) => "requestDigest" in step ? step.requestDigest : step.stepId
1017
+ )
1018
+ });
1019
+ const finalSemanticDigest = options.expected?.finalSemanticDigest ?? digestUIFixtureJson({
1020
+ digestVersion: "ui-semantic@1",
1021
+ fixtureId: options.id,
1022
+ frameId: finalFrame.id,
1023
+ projectionDigest: finalFrame.projectionDigest
1024
+ });
1025
+ return parseUIScenarioFixture(
1026
+ canonicalizeUIScenarioFixture({
1027
+ schemaVersion: 1,
1028
+ browserInteractionProtocol: DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,
1029
+ id: options.id,
1030
+ title: options.title,
1031
+ gameId: options.gameId,
1032
+ tags: [...options.tags ?? []],
1033
+ source: options.source,
1034
+ viewer: options.viewer,
1035
+ environment: options.environment,
1036
+ frames: options.frames,
1037
+ transport: [...options.transport ?? []],
1038
+ replay,
1039
+ expected: {
1040
+ initialProjectionDigest: options.expected?.initialProjectionDigest ?? firstFrame.projectionDigest,
1041
+ finalProjectionDigest: options.expected?.finalProjectionDigest ?? finalFrame.projectionDigest,
1042
+ finalSemanticDigest,
1043
+ submissionDigest
1044
+ }
1045
+ })
1046
+ );
1047
+ }
1048
+ function assertDeterministicUIScenarioFixture(first, second) {
1049
+ const firstBytes = serializeUIScenarioFixture(first);
1050
+ const secondBytes = serializeUIScenarioFixture(second);
1051
+ if (firstBytes !== secondBytes) {
1052
+ throw new Error(
1053
+ `UI scenario fixture '${first.id}' is non-deterministic across compilation runs.`
1054
+ );
1055
+ }
1056
+ }
1057
+ function assertUniqueReplayIdentity(step, candidates) {
1058
+ if (candidates.length !== 1) {
1059
+ throw new Error(
1060
+ `Replay step '${step.stepId}' resolved ${candidates.length} identities; expected exactly one.`
1061
+ );
1062
+ }
1063
+ const candidate = candidates[0];
1064
+ if (!candidate) {
1065
+ throw new Error(`Replay step '${step.stepId}' did not resolve.`);
1066
+ }
1067
+ const expected = step.expectedIdentity;
1068
+ if (!expected) {
1069
+ return candidate;
1070
+ }
1071
+ for (const key of [
1072
+ "surface",
1073
+ "scopeId",
1074
+ "interactionKey",
1075
+ "interactionId",
1076
+ "actuatorId",
1077
+ "descriptorDigest",
1078
+ "draftDigest"
1079
+ ]) {
1080
+ const expectedValue = expected[key];
1081
+ if (expectedValue !== void 0 && candidate[key] !== expectedValue) {
1082
+ throw new Error(
1083
+ `Replay step '${step.stepId}' resolved ${key} '${String(
1084
+ candidate[key]
1085
+ )}', expected '${expectedValue}'.`
1086
+ );
1087
+ }
1088
+ }
1089
+ return candidate;
1090
+ }
1091
+ function assertUIStepExpectationSatisfied(stepId, expected, actual) {
1092
+ for (const key of [
1093
+ "frameId",
1094
+ "projectionDigest",
1095
+ "semanticDigest",
1096
+ "draftDigest",
1097
+ "submissionDigest",
1098
+ "focusedInteractionKey"
1099
+ ]) {
1100
+ if (expected[key] !== void 0 && expected[key] !== actual[key]) {
1101
+ throw new Error(
1102
+ `Replay step '${stepId}' expected ${key} '${expected[key]}', received '${actual[key]}'.`
1103
+ );
1104
+ }
1105
+ }
1106
+ if (expected.visibleInteractionKeys) {
1107
+ const actualKeys = new Set(actual.visibleInteractionKeys ?? []);
1108
+ const missing = expected.visibleInteractionKeys.filter(
1109
+ (key) => !actualKeys.has(key)
1110
+ );
1111
+ if (missing.length > 0) {
1112
+ throw new Error(
1113
+ `Replay step '${stepId}' missing visible interactions: ${missing.join(
1114
+ ", "
1115
+ )}.`
1116
+ );
1117
+ }
1118
+ }
1119
+ }
669
1120
  export {
670
1121
  StaleContractArtifactError,
1122
+ UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION,
1123
+ UI_SCENARIO_FIXTURE_SCHEMA_VERSION,
1124
+ UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR,
1125
+ assertDeterministicUIScenarioFixture,
1126
+ assertSupportedBrowserInteractionProtocol,
1127
+ assertUIStepExpectationSatisfied,
1128
+ assertUniqueReplayIdentity,
1129
+ canonicalUIFixtureJson,
1130
+ canonicalizeUIFixtureJson,
1131
+ canonicalizeUIScenarioFixture,
1132
+ compileUIScenarioFixture,
671
1133
  createExpectApi,
672
1134
  createTestRuntime,
673
1135
  defineBase,
674
1136
  defineScenario,
675
- isStaleContractArtifactError
1137
+ digestUIFixtureJson,
1138
+ digestUIFixtureRequest,
1139
+ digestUIScenarioFixture,
1140
+ isSha256Digest,
1141
+ isStaleContractArtifactError,
1142
+ parseUIScenarioFixture,
1143
+ parseUIScenarioFixtureBundleIndex,
1144
+ portableSemanticReplayStepSchema,
1145
+ serializeUIScenarioFixture,
1146
+ uiFixtureFrameSchema,
1147
+ uiFixturePluginStateSnapshotSchema,
1148
+ uiFixtureTransportExchangeSchema,
1149
+ uiReplayExecutionSchema,
1150
+ uiReplayRequestSchema,
1151
+ uiResolvedReplayIdentitySchema,
1152
+ uiScenarioFixtureBundleIndexSchema,
1153
+ uiScenarioFixtureSchema,
1154
+ uiScenarioReplayStepSchema,
1155
+ uiStepExpectationSchema
676
1156
  };
677
1157
  //# sourceMappingURL=testing.js.map