@fanfare-io/fanfare-sdk-core 0.1.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.
Files changed (170) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +44 -0
  3. package/dist/adapters/google-analytics.d.ts +12 -0
  4. package/dist/adapters/google-analytics.js +1 -0
  5. package/dist/adapters/index.d.ts +9 -0
  6. package/dist/adapters/index.js +1 -0
  7. package/dist/adapters/types.d.ts +9 -0
  8. package/dist/appointments/appointment.module.d.ts +32 -0
  9. package/dist/appointments/appointment.module.js +1 -0
  10. package/dist/appointments/index.d.ts +2 -0
  11. package/dist/appointments/public.d.ts +1 -0
  12. package/dist/appointments/public.js +1 -0
  13. package/dist/appointments/types.d.ts +47 -0
  14. package/dist/auctions/auction.module.d.ts +58 -0
  15. package/dist/auctions/auction.module.js +1 -0
  16. package/dist/auctions/index.d.ts +5 -0
  17. package/dist/auctions/public.d.ts +5 -0
  18. package/dist/auctions/public.js +1 -0
  19. package/dist/auctions/types.d.ts +97 -0
  20. package/dist/auth/auth.module.d.ts +71 -0
  21. package/dist/auth/auth.module.js +1 -0
  22. package/dist/auth/index.d.ts +1 -0
  23. package/dist/auth/index.js +1 -0
  24. package/dist/auth/types.d.ts +112 -0
  25. package/dist/beacon/batching.d.ts +52 -0
  26. package/dist/beacon/batching.js +1 -0
  27. package/dist/beacon/beacon.module.d.ts +58 -0
  28. package/dist/beacon/beacon.module.js +1 -0
  29. package/dist/beacon/enrichment.d.ts +16 -0
  30. package/dist/beacon/enrichment.js +1 -0
  31. package/dist/beacon/index.d.ts +12 -0
  32. package/dist/beacon/public.d.ts +9 -0
  33. package/dist/beacon/public.js +1 -0
  34. package/dist/beacon/types.d.ts +103 -0
  35. package/dist/beacon/validation.d.ts +24 -0
  36. package/dist/beacon/validation.js +1 -0
  37. package/dist/challenges/challenge.module.d.ts +9 -0
  38. package/dist/challenges/challenge.module.js +1 -0
  39. package/dist/challenges/index.d.ts +3 -0
  40. package/dist/challenges/public.d.ts +9 -0
  41. package/dist/challenges/public.js +1 -0
  42. package/dist/challenges/types.d.ts +33 -0
  43. package/dist/config/index.d.ts +44 -0
  44. package/dist/config/index.js +1 -0
  45. package/dist/core/client.d.ts +15 -0
  46. package/dist/core/client.js +2 -0
  47. package/dist/core/errors.d.ts +175 -0
  48. package/dist/core/errors.js +1 -0
  49. package/dist/core/http.d.ts +87 -0
  50. package/dist/core/http.js +1 -0
  51. package/dist/core/logger.d.ts +46 -0
  52. package/dist/core/logger.js +1 -0
  53. package/dist/core/money.d.ts +10 -0
  54. package/dist/core/money.js +1 -0
  55. package/dist/core/parse-response.d.ts +62 -0
  56. package/dist/core/parse-response.js +1 -0
  57. package/dist/core/utils.d.ts +67 -0
  58. package/dist/core/utils.js +1 -0
  59. package/dist/draws/draw.module.d.ts +40 -0
  60. package/dist/draws/draw.module.js +1 -0
  61. package/dist/draws/index.d.ts +5 -0
  62. package/dist/draws/public.d.ts +6 -0
  63. package/dist/draws/public.js +1 -0
  64. package/dist/draws/types.d.ts +90 -0
  65. package/dist/draws/types.js +1 -0
  66. package/dist/errors.d.ts +5 -0
  67. package/dist/errors.js +1 -0
  68. package/dist/events.d.ts +5 -0
  69. package/dist/events.js +1 -0
  70. package/dist/experiences/distribution-monitor.runtime.d.ts +12 -0
  71. package/dist/experiences/distribution-monitor.runtime.js +1 -0
  72. package/dist/experiences/distribution-monitor.types.d.ts +62 -0
  73. package/dist/experiences/experience.module.d.ts +88 -0
  74. package/dist/experiences/experience.module.js +1 -0
  75. package/dist/experiences/index.d.ts +3 -0
  76. package/dist/experiences/index.js +1 -0
  77. package/dist/experiences/journey-contract.fixtures.d.ts +9 -0
  78. package/dist/experiences/journey-view.d.ts +22 -0
  79. package/dist/experiences/journey-view.js +1 -0
  80. package/dist/experiences/journey.d.ts +89 -0
  81. package/dist/experiences/journey.js +1 -0
  82. package/dist/experiences/journey.machine.d.ts +79 -0
  83. package/dist/experiences/journey.machine.js +1 -0
  84. package/dist/experiences/journey.types.d.ts +395 -0
  85. package/dist/experiences/public.d.ts +13 -0
  86. package/dist/experiences/public.js +1 -0
  87. package/dist/experiences/types.d.ts +161 -0
  88. package/dist/handoff/handoff.module.d.ts +184 -0
  89. package/dist/handoff/handoff.module.js +1 -0
  90. package/dist/handoff/index.d.ts +5 -0
  91. package/dist/handoff/index.js +1 -0
  92. package/dist/index.d.ts +11 -0
  93. package/dist/index.js +1 -0
  94. package/dist/internals.d.ts +11 -0
  95. package/dist/internals.js +1 -0
  96. package/dist/queues/index.d.ts +5 -0
  97. package/dist/queues/index.js +1 -0
  98. package/dist/queues/qualitative-bucket.d.ts +12 -0
  99. package/dist/queues/qualitative-bucket.js +1 -0
  100. package/dist/queues/queue.module.d.ts +42 -0
  101. package/dist/queues/queue.module.js +1 -0
  102. package/dist/queues/types.d.ts +112 -0
  103. package/dist/queues/types.js +1 -0
  104. package/dist/security/admission-proof.d.ts +15 -0
  105. package/dist/security/admission-proof.js +1 -0
  106. package/dist/state/capability-token-registry.d.ts +44 -0
  107. package/dist/state/capability-token-registry.js +1 -0
  108. package/dist/state/events.d.ts +342 -0
  109. package/dist/state/events.js +1 -0
  110. package/dist/state/store.d.ts +48 -0
  111. package/dist/state/store.js +1 -0
  112. package/dist/sync/broadcast-transport.d.ts +19 -0
  113. package/dist/sync/broadcast-transport.js +1 -0
  114. package/dist/sync/cross-tab-coordinator.d.ts +44 -0
  115. package/dist/sync/cross-tab-coordinator.js +1 -0
  116. package/dist/sync/index.d.ts +8 -0
  117. package/dist/sync/localstorage-transport.d.ts +32 -0
  118. package/dist/sync/localstorage-transport.js +1 -0
  119. package/dist/sync/protocol-transport.d.ts +51 -0
  120. package/dist/sync/protocol-transport.js +1 -0
  121. package/dist/sync/protocol.d.ts +254 -0
  122. package/dist/sync/protocol.js +1 -0
  123. package/dist/sync/recovery.d.ts +68 -0
  124. package/dist/sync/transport-factory.d.ts +16 -0
  125. package/dist/sync/transport-factory.js +1 -0
  126. package/dist/sync/transport-interface.d.ts +33 -0
  127. package/dist/sync/transport.d.ts +49 -0
  128. package/dist/sync/transport.js +1 -0
  129. package/dist/test-utils/harness-scenarios.d.ts +71 -0
  130. package/dist/test-utils/harness-scenarios.js +1 -0
  131. package/dist/test-utils/index.d.ts +12 -0
  132. package/dist/test-utils/index.js +1 -0
  133. package/dist/test-utils/mock-journey.d.ts +63 -0
  134. package/dist/test-utils/mock-journey.js +1 -0
  135. package/dist/test-utils/mock-sdk-vitest.d.ts +80 -0
  136. package/dist/test-utils/mock-sdk-vitest.js +1 -0
  137. package/dist/test-utils/mock-sdk.d.ts +22 -0
  138. package/dist/test-utils/mock-sdk.js +1 -0
  139. package/dist/test-utils/mock-server.d.ts +105 -0
  140. package/dist/test-utils/mock-server.js +1 -0
  141. package/dist/test-utils/sdk-factory.d.ts +3 -0
  142. package/dist/test-utils/sdk-factory.js +1 -0
  143. package/dist/test-utils/verification-scenarios.d.ts +43 -0
  144. package/dist/test-utils/verification-scenarios.js +1 -0
  145. package/dist/test-utils/verification-state.d.ts +1 -0
  146. package/dist/test-utils/verification-state.js +1 -0
  147. package/dist/theme.d.ts +8 -0
  148. package/dist/theme.js +1 -0
  149. package/dist/timed-releases/index.d.ts +6 -0
  150. package/dist/timed-releases/public.d.ts +6 -0
  151. package/dist/timed-releases/public.js +1 -0
  152. package/dist/timed-releases/timed-release.module.d.ts +31 -0
  153. package/dist/timed-releases/timed-release.module.js +1 -0
  154. package/dist/timed-releases/types.d.ts +70 -0
  155. package/dist/timed-releases/types.js +1 -0
  156. package/dist/types/distribution-type.d.ts +45 -0
  157. package/dist/types/index.d.ts +178 -0
  158. package/dist/utils/fingerprint.module.d.ts +27 -0
  159. package/dist/utils/fingerprint.module.js +1 -0
  160. package/dist/utils/index.d.ts +4 -0
  161. package/dist/version.d.ts +5 -0
  162. package/dist/version.js +1 -0
  163. package/dist/waitlists/index.d.ts +2 -0
  164. package/dist/waitlists/public.d.ts +6 -0
  165. package/dist/waitlists/public.js +1 -0
  166. package/dist/waitlists/types.d.ts +50 -0
  167. package/dist/waitlists/types.js +1 -0
  168. package/dist/waitlists/waitlist.module.d.ts +17 -0
  169. package/dist/waitlists/waitlist.module.js +1 -0
  170. package/package.json +205 -0
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Message protocol schemas and types for inter-tab coordination.
3
+ */
4
+ import * as v from "valibot";
5
+ declare const DurableBootstrapRequestMessageSchema: v.IntersectSchema<[v.ObjectSchema<{
6
+ readonly id: v.StringSchema<undefined>;
7
+ readonly timestamp: v.NumberSchema<undefined>;
8
+ readonly source: v.StringSchema<undefined>;
9
+ readonly version: v.NumberSchema<undefined>;
10
+ }, undefined>, v.ObjectSchema<{
11
+ readonly type: v.LiteralSchema<"durable:bootstrap:request", undefined>;
12
+ readonly payload: v.ObjectSchema<{}, undefined>;
13
+ }, undefined>], undefined>;
14
+ declare const DurableBootstrapResponseMessageSchema: v.IntersectSchema<[v.ObjectSchema<{
15
+ readonly id: v.StringSchema<undefined>;
16
+ readonly timestamp: v.NumberSchema<undefined>;
17
+ readonly source: v.StringSchema<undefined>;
18
+ readonly version: v.NumberSchema<undefined>;
19
+ }, undefined>, v.ObjectSchema<{
20
+ readonly type: v.LiteralSchema<"durable:bootstrap:response", undefined>;
21
+ readonly payload: v.ObjectSchema<{
22
+ readonly session: v.UnknownSchema;
23
+ readonly sessionVersion: v.NumberSchema<undefined>;
24
+ readonly capabilityTokens: v.UnknownSchema;
25
+ readonly capabilityTokensVersion: v.NumberSchema<undefined>;
26
+ readonly distributionCapabilityIndex: v.UnknownSchema;
27
+ readonly distributionCapabilityIndexVersion: v.NumberSchema<undefined>;
28
+ readonly journeys: v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
29
+ readonly snapshot: v.UnknownSchema;
30
+ readonly version: v.NumberSchema<undefined>;
31
+ }, undefined>, undefined>;
32
+ }, undefined>;
33
+ }, undefined>], undefined>;
34
+ declare const SessionUpdateMessageSchema: v.IntersectSchema<[v.ObjectSchema<{
35
+ readonly id: v.StringSchema<undefined>;
36
+ readonly timestamp: v.NumberSchema<undefined>;
37
+ readonly source: v.StringSchema<undefined>;
38
+ readonly version: v.NumberSchema<undefined>;
39
+ }, undefined>, v.ObjectSchema<{
40
+ readonly type: v.LiteralSchema<"session:update", undefined>;
41
+ readonly payload: v.ObjectSchema<{
42
+ readonly value: v.UnknownSchema;
43
+ readonly version: v.NumberSchema<undefined>;
44
+ }, undefined>;
45
+ }, undefined>], undefined>;
46
+ declare const CapabilityTokensUpdateMessageSchema: v.IntersectSchema<[v.ObjectSchema<{
47
+ readonly id: v.StringSchema<undefined>;
48
+ readonly timestamp: v.NumberSchema<undefined>;
49
+ readonly source: v.StringSchema<undefined>;
50
+ readonly version: v.NumberSchema<undefined>;
51
+ }, undefined>, v.ObjectSchema<{
52
+ readonly type: v.LiteralSchema<"capability-tokens:update", undefined>;
53
+ readonly payload: v.ObjectSchema<{
54
+ readonly value: v.UnknownSchema;
55
+ readonly version: v.NumberSchema<undefined>;
56
+ }, undefined>;
57
+ }, undefined>], undefined>;
58
+ declare const DistributionCapabilityIndexUpdateMessageSchema: v.IntersectSchema<[v.ObjectSchema<{
59
+ readonly id: v.StringSchema<undefined>;
60
+ readonly timestamp: v.NumberSchema<undefined>;
61
+ readonly source: v.StringSchema<undefined>;
62
+ readonly version: v.NumberSchema<undefined>;
63
+ }, undefined>, v.ObjectSchema<{
64
+ readonly type: v.LiteralSchema<"distribution-capability-index:update", undefined>;
65
+ readonly payload: v.ObjectSchema<{
66
+ readonly value: v.UnknownSchema;
67
+ readonly version: v.NumberSchema<undefined>;
68
+ }, undefined>;
69
+ }, undefined>], undefined>;
70
+ declare const JourneyUpsertMessageSchema: v.IntersectSchema<[v.ObjectSchema<{
71
+ readonly id: v.StringSchema<undefined>;
72
+ readonly timestamp: v.NumberSchema<undefined>;
73
+ readonly source: v.StringSchema<undefined>;
74
+ readonly version: v.NumberSchema<undefined>;
75
+ }, undefined>, v.ObjectSchema<{
76
+ readonly type: v.LiteralSchema<"journey:upsert", undefined>;
77
+ readonly payload: v.ObjectSchema<{
78
+ readonly experienceId: v.StringSchema<undefined>;
79
+ readonly snapshot: v.UnknownSchema;
80
+ readonly version: v.NumberSchema<undefined>;
81
+ }, undefined>;
82
+ }, undefined>], undefined>;
83
+ declare const JourneyRemoveMessageSchema: v.IntersectSchema<[v.ObjectSchema<{
84
+ readonly id: v.StringSchema<undefined>;
85
+ readonly timestamp: v.NumberSchema<undefined>;
86
+ readonly source: v.StringSchema<undefined>;
87
+ readonly version: v.NumberSchema<undefined>;
88
+ }, undefined>, v.ObjectSchema<{
89
+ readonly type: v.LiteralSchema<"journey:remove", undefined>;
90
+ readonly payload: v.ObjectSchema<{
91
+ readonly experienceId: v.StringSchema<undefined>;
92
+ readonly version: v.NumberSchema<undefined>;
93
+ }, undefined>;
94
+ }, undefined>], undefined>;
95
+ declare const RuntimeStateMessageSchema: v.IntersectSchema<[v.ObjectSchema<{
96
+ readonly id: v.StringSchema<undefined>;
97
+ readonly timestamp: v.NumberSchema<undefined>;
98
+ readonly source: v.StringSchema<undefined>;
99
+ readonly version: v.NumberSchema<undefined>;
100
+ }, undefined>, v.ObjectSchema<{
101
+ readonly type: v.LiteralSchema<"runtime:state", undefined>;
102
+ readonly payload: v.ObjectSchema<{
103
+ readonly experienceId: v.StringSchema<undefined>;
104
+ readonly sequenceId: v.StringSchema<undefined>;
105
+ readonly participationId: v.StringSchema<undefined>;
106
+ readonly participationType: v.PicklistSchema<["queue", "draw", "auction", "timed_release", "appointment"], undefined>;
107
+ readonly leaderId: v.StringSchema<undefined>;
108
+ readonly runtimeVersion: v.NumberSchema<undefined>;
109
+ readonly state: v.NullableSchema<v.UnknownSchema, undefined>;
110
+ }, undefined>;
111
+ }, undefined>], undefined>;
112
+ declare const HeartbeatMessageSchema: v.IntersectSchema<[v.ObjectSchema<{
113
+ readonly id: v.StringSchema<undefined>;
114
+ readonly timestamp: v.NumberSchema<undefined>;
115
+ readonly source: v.StringSchema<undefined>;
116
+ readonly version: v.NumberSchema<undefined>;
117
+ }, undefined>, v.ObjectSchema<{
118
+ readonly type: v.LiteralSchema<"heartbeat", undefined>;
119
+ readonly payload: v.ObjectSchema<{
120
+ readonly active: v.BooleanSchema<undefined>;
121
+ }, undefined>;
122
+ }, undefined>], undefined>;
123
+ export declare const SyncMessageSchema: v.UnionSchema<[v.IntersectSchema<[v.ObjectSchema<{
124
+ readonly id: v.StringSchema<undefined>;
125
+ readonly timestamp: v.NumberSchema<undefined>;
126
+ readonly source: v.StringSchema<undefined>;
127
+ readonly version: v.NumberSchema<undefined>;
128
+ }, undefined>, v.ObjectSchema<{
129
+ readonly type: v.LiteralSchema<"durable:bootstrap:request", undefined>;
130
+ readonly payload: v.ObjectSchema<{}, undefined>;
131
+ }, undefined>], undefined>, v.IntersectSchema<[v.ObjectSchema<{
132
+ readonly id: v.StringSchema<undefined>;
133
+ readonly timestamp: v.NumberSchema<undefined>;
134
+ readonly source: v.StringSchema<undefined>;
135
+ readonly version: v.NumberSchema<undefined>;
136
+ }, undefined>, v.ObjectSchema<{
137
+ readonly type: v.LiteralSchema<"durable:bootstrap:response", undefined>;
138
+ readonly payload: v.ObjectSchema<{
139
+ readonly session: v.UnknownSchema;
140
+ readonly sessionVersion: v.NumberSchema<undefined>;
141
+ readonly capabilityTokens: v.UnknownSchema;
142
+ readonly capabilityTokensVersion: v.NumberSchema<undefined>;
143
+ readonly distributionCapabilityIndex: v.UnknownSchema;
144
+ readonly distributionCapabilityIndexVersion: v.NumberSchema<undefined>;
145
+ readonly journeys: v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
146
+ readonly snapshot: v.UnknownSchema;
147
+ readonly version: v.NumberSchema<undefined>;
148
+ }, undefined>, undefined>;
149
+ }, undefined>;
150
+ }, undefined>], undefined>, v.IntersectSchema<[v.ObjectSchema<{
151
+ readonly id: v.StringSchema<undefined>;
152
+ readonly timestamp: v.NumberSchema<undefined>;
153
+ readonly source: v.StringSchema<undefined>;
154
+ readonly version: v.NumberSchema<undefined>;
155
+ }, undefined>, v.ObjectSchema<{
156
+ readonly type: v.LiteralSchema<"session:update", undefined>;
157
+ readonly payload: v.ObjectSchema<{
158
+ readonly value: v.UnknownSchema;
159
+ readonly version: v.NumberSchema<undefined>;
160
+ }, undefined>;
161
+ }, undefined>], undefined>, v.IntersectSchema<[v.ObjectSchema<{
162
+ readonly id: v.StringSchema<undefined>;
163
+ readonly timestamp: v.NumberSchema<undefined>;
164
+ readonly source: v.StringSchema<undefined>;
165
+ readonly version: v.NumberSchema<undefined>;
166
+ }, undefined>, v.ObjectSchema<{
167
+ readonly type: v.LiteralSchema<"capability-tokens:update", undefined>;
168
+ readonly payload: v.ObjectSchema<{
169
+ readonly value: v.UnknownSchema;
170
+ readonly version: v.NumberSchema<undefined>;
171
+ }, undefined>;
172
+ }, undefined>], undefined>, v.IntersectSchema<[v.ObjectSchema<{
173
+ readonly id: v.StringSchema<undefined>;
174
+ readonly timestamp: v.NumberSchema<undefined>;
175
+ readonly source: v.StringSchema<undefined>;
176
+ readonly version: v.NumberSchema<undefined>;
177
+ }, undefined>, v.ObjectSchema<{
178
+ readonly type: v.LiteralSchema<"distribution-capability-index:update", undefined>;
179
+ readonly payload: v.ObjectSchema<{
180
+ readonly value: v.UnknownSchema;
181
+ readonly version: v.NumberSchema<undefined>;
182
+ }, undefined>;
183
+ }, undefined>], undefined>, v.IntersectSchema<[v.ObjectSchema<{
184
+ readonly id: v.StringSchema<undefined>;
185
+ readonly timestamp: v.NumberSchema<undefined>;
186
+ readonly source: v.StringSchema<undefined>;
187
+ readonly version: v.NumberSchema<undefined>;
188
+ }, undefined>, v.ObjectSchema<{
189
+ readonly type: v.LiteralSchema<"journey:upsert", undefined>;
190
+ readonly payload: v.ObjectSchema<{
191
+ readonly experienceId: v.StringSchema<undefined>;
192
+ readonly snapshot: v.UnknownSchema;
193
+ readonly version: v.NumberSchema<undefined>;
194
+ }, undefined>;
195
+ }, undefined>], undefined>, v.IntersectSchema<[v.ObjectSchema<{
196
+ readonly id: v.StringSchema<undefined>;
197
+ readonly timestamp: v.NumberSchema<undefined>;
198
+ readonly source: v.StringSchema<undefined>;
199
+ readonly version: v.NumberSchema<undefined>;
200
+ }, undefined>, v.ObjectSchema<{
201
+ readonly type: v.LiteralSchema<"journey:remove", undefined>;
202
+ readonly payload: v.ObjectSchema<{
203
+ readonly experienceId: v.StringSchema<undefined>;
204
+ readonly version: v.NumberSchema<undefined>;
205
+ }, undefined>;
206
+ }, undefined>], undefined>, v.IntersectSchema<[v.ObjectSchema<{
207
+ readonly id: v.StringSchema<undefined>;
208
+ readonly timestamp: v.NumberSchema<undefined>;
209
+ readonly source: v.StringSchema<undefined>;
210
+ readonly version: v.NumberSchema<undefined>;
211
+ }, undefined>, v.ObjectSchema<{
212
+ readonly type: v.LiteralSchema<"runtime:state", undefined>;
213
+ readonly payload: v.ObjectSchema<{
214
+ readonly experienceId: v.StringSchema<undefined>;
215
+ readonly sequenceId: v.StringSchema<undefined>;
216
+ readonly participationId: v.StringSchema<undefined>;
217
+ readonly participationType: v.PicklistSchema<["queue", "draw", "auction", "timed_release", "appointment"], undefined>;
218
+ readonly leaderId: v.StringSchema<undefined>;
219
+ readonly runtimeVersion: v.NumberSchema<undefined>;
220
+ readonly state: v.NullableSchema<v.UnknownSchema, undefined>;
221
+ }, undefined>;
222
+ }, undefined>], undefined>, v.IntersectSchema<[v.ObjectSchema<{
223
+ readonly id: v.StringSchema<undefined>;
224
+ readonly timestamp: v.NumberSchema<undefined>;
225
+ readonly source: v.StringSchema<undefined>;
226
+ readonly version: v.NumberSchema<undefined>;
227
+ }, undefined>, v.ObjectSchema<{
228
+ readonly type: v.LiteralSchema<"heartbeat", undefined>;
229
+ readonly payload: v.ObjectSchema<{
230
+ readonly active: v.BooleanSchema<undefined>;
231
+ }, undefined>;
232
+ }, undefined>], undefined>], undefined>;
233
+ export type SyncMessage = v.InferOutput<typeof SyncMessageSchema>;
234
+ export type DurableBootstrapRequestMessage = v.InferOutput<typeof DurableBootstrapRequestMessageSchema>;
235
+ export type DurableBootstrapResponseMessage = v.InferOutput<typeof DurableBootstrapResponseMessageSchema>;
236
+ export type SessionUpdateMessage = v.InferOutput<typeof SessionUpdateMessageSchema>;
237
+ export type CapabilityTokensUpdateMessage = v.InferOutput<typeof CapabilityTokensUpdateMessageSchema>;
238
+ export type DistributionCapabilityIndexUpdateMessage = v.InferOutput<typeof DistributionCapabilityIndexUpdateMessageSchema>;
239
+ export type JourneyUpsertMessage = v.InferOutput<typeof JourneyUpsertMessageSchema>;
240
+ export type JourneyRemoveMessage = v.InferOutput<typeof JourneyRemoveMessageSchema>;
241
+ export type RuntimeStateMessage = v.InferOutput<typeof RuntimeStateMessageSchema>;
242
+ export type HeartbeatMessage = v.InferOutput<typeof HeartbeatMessageSchema>;
243
+ export declare function isDurableBootstrapRequestMessage(message: SyncMessage): message is DurableBootstrapRequestMessage;
244
+ export declare function isDurableBootstrapResponseMessage(message: SyncMessage): message is DurableBootstrapResponseMessage;
245
+ export declare function isSessionUpdateMessage(message: SyncMessage): message is SessionUpdateMessage;
246
+ export declare function isCapabilityTokensUpdateMessage(message: SyncMessage): message is CapabilityTokensUpdateMessage;
247
+ export declare function isDistributionCapabilityIndexUpdateMessage(message: SyncMessage): message is DistributionCapabilityIndexUpdateMessage;
248
+ export declare function isJourneyUpsertMessage(message: SyncMessage): message is JourneyUpsertMessage;
249
+ export declare function isJourneyRemoveMessage(message: SyncMessage): message is JourneyRemoveMessage;
250
+ export declare function isRuntimeStateMessage(message: SyncMessage): message is RuntimeStateMessage;
251
+ export declare function isHeartbeatMessage(message: SyncMessage): message is HeartbeatMessage;
252
+ export declare const PROTOCOL_VERSION = 2;
253
+ export declare const DEFAULT_CHANNEL_NAME = "fanfare-sdk-sync";
254
+ export {};
@@ -0,0 +1 @@
1
+ import*as e from"valibot";const t=e.object({id:e.string(),timestamp:e.number(),source:e.string(),version:e.number()}),n=e.intersect([t,e.object({type:e.literal("durable:bootstrap:request"),payload:e.object({})})]),r=e.object({snapshot:e.unknown(),version:e.number()}),i=e.intersect([t,e.object({type:e.literal("durable:bootstrap:response"),payload:e.object({session:e.unknown(),sessionVersion:e.number(),capabilityTokens:e.unknown(),capabilityTokensVersion:e.number(),distributionCapabilityIndex:e.unknown(),distributionCapabilityIndexVersion:e.number(),journeys:e.record(e.string(),r)})})]),o=e.intersect([t,e.object({type:e.literal("session:update"),payload:e.object({value:e.unknown(),version:e.number()})})]),a=e.intersect([t,e.object({type:e.literal("capability-tokens:update"),payload:e.object({value:e.unknown(),version:e.number()})})]),s=e.intersect([t,e.object({type:e.literal("distribution-capability-index:update"),payload:e.object({value:e.unknown(),version:e.number()})})]),u=e.intersect([t,e.object({type:e.literal("journey:upsert"),payload:e.object({experienceId:e.string(),snapshot:e.unknown(),version:e.number()})})]),p=e.intersect([t,e.object({type:e.literal("journey:remove"),payload:e.object({experienceId:e.string(),version:e.number()})})]),c=e.intersect([t,e.object({type:e.literal("runtime:state"),payload:e.object({experienceId:e.string(),sequenceId:e.string(),participationId:e.string(),participationType:e.picklist(["queue","draw","auction","timed_release","appointment"]),leaderId:e.string(),runtimeVersion:e.number(),state:e.nullable(e.unknown())})})]),b=e.intersect([t,e.object({type:e.literal("heartbeat"),payload:e.object({active:e.boolean()})})]),l=e.union([n,i,o,a,s,u,p,c,b]);function y(e){return"durable:bootstrap:request"===e.type}function d(e){return"durable:bootstrap:response"===e.type}function j(e){return"session:update"===e.type}function m(e){return"capability-tokens:update"===e.type}function k(e){return"distribution-capability-index:update"===e.type}function v(e){return"journey:upsert"===e.type}function f(e){return"journey:remove"===e.type}function w(e){return"runtime:state"===e.type}function g(e){return"heartbeat"===e.type}const x=2,I="fanfare-sdk-sync";export{I as DEFAULT_CHANNEL_NAME,x as PROTOCOL_VERSION,l as SyncMessageSchema,m as isCapabilityTokensUpdateMessage,k as isDistributionCapabilityIndexUpdateMessage,y as isDurableBootstrapRequestMessage,d as isDurableBootstrapResponseMessage,g as isHeartbeatMessage,f as isJourneyRemoveMessage,v as isJourneyUpsertMessage,w as isRuntimeStateMessage,j as isSessionUpdateMessage};
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Recovery management for sync failures and storage issues
3
+ *
4
+ * Handles storage quota errors, sync failures, and implements retry strategies
5
+ * with exponential backoff and update queuing to prevent race conditions.
6
+ */
7
+ export interface RecoveryStrategy {
8
+ maxRetries?: number;
9
+ backoffMs?: number;
10
+ onRecoveryFailed?: (error: Error) => void;
11
+ }
12
+ export interface UpdateQueueItem<T> {
13
+ update: T;
14
+ timestamp: number;
15
+ }
16
+ export interface UpdateQueue<T> {
17
+ enqueue: (update: T) => void;
18
+ process: (handler: (update: T) => Promise<void>) => Promise<void>;
19
+ clear: () => void;
20
+ size: () => number;
21
+ }
22
+ /**
23
+ * Manages recovery from sync failures and storage issues
24
+ */
25
+ export declare class RecoveryManager {
26
+ private logger;
27
+ private strategy;
28
+ constructor(strategy?: RecoveryStrategy);
29
+ /**
30
+ * Attempt to recover from storage quota errors
31
+ */
32
+ handleStorageQuotaError(): Promise<void>;
33
+ /**
34
+ * Recover from sync failures with retry
35
+ */
36
+ recoverSync(operation: () => Promise<void>): Promise<void>;
37
+ /**
38
+ * Handle race conditions by implementing a queue
39
+ */
40
+ createUpdateQueue<T>(): UpdateQueue<T>;
41
+ /**
42
+ * Check if localStorage is available and has space
43
+ */
44
+ checkStorageAvailability(): {
45
+ available: boolean;
46
+ estimatedSpace?: number;
47
+ };
48
+ /**
49
+ * Create a fallback for when sync is not available
50
+ */
51
+ createFallbackSync(): {
52
+ save: (key: string, value: unknown) => void;
53
+ load: (key: string) => unknown | null;
54
+ };
55
+ /**
56
+ * Monitor storage usage and warn when approaching limits
57
+ */
58
+ monitorStorageUsage(): Promise<{
59
+ used: number;
60
+ quota: number;
61
+ percentage: number;
62
+ warning: boolean;
63
+ }>;
64
+ /**
65
+ * Get current recovery strategy
66
+ */
67
+ getStrategy(): Required<RecoveryStrategy>;
68
+ }
@@ -0,0 +1,16 @@
1
+ import { ITransport } from './transport-interface';
2
+ /**
3
+ * Create the best available transport for the current environment
4
+ *
5
+ * @param channel - The channel name for cross-tab communication
6
+ * @returns A transport implementation or null if no transport is available
7
+ */
8
+ export declare function createTransport(channel: string): ITransport | null;
9
+ /**
10
+ * Get information about available transports
11
+ */
12
+ export declare function getTransportInfo(): {
13
+ broadcastChannel: boolean;
14
+ localStorage: boolean;
15
+ available: boolean;
16
+ };
@@ -0,0 +1 @@
1
+ import{getLogger as r}from"../core/logger.js";import{isBroadcastChannelSupported as n,BroadcastChannelTransport as o}from"./broadcast-transport.js";import{isLocalStorageSupported as a,LocalStorageTransport as t}from"./localstorage-transport.js";function i(i){const l=r();if(n()){const r=new o(i);if(r.isAvailable())return l.info("Using BroadcastChannel transport",{channel:i}),r}if(a()){const r=new t(i);if(r.isAvailable())return l.info("Using localStorage transport (fallback)",{channel:i}),r}return l.warn("No transport available for inter-tab communication"),null}export{i as createTransport};
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Transport interface for inter-tab communication
3
+ *
4
+ * This interface defines the contract that all transport implementations
5
+ * must follow, allowing for different communication mechanisms while
6
+ * maintaining a consistent API.
7
+ */
8
+ /**
9
+ * Generic transport interface for cross-tab communication
10
+ */
11
+ export interface ITransport {
12
+ /**
13
+ * Send a message to other tabs
14
+ */
15
+ send(message: unknown): void;
16
+ /**
17
+ * Register a message listener
18
+ * @returns Unsubscribe function
19
+ */
20
+ onMessage(handler: (event: MessageEvent) => void): () => void;
21
+ /**
22
+ * Close the transport and clean up resources
23
+ */
24
+ close(): void;
25
+ /**
26
+ * Check if transport is available
27
+ */
28
+ isAvailable(): boolean;
29
+ }
30
+ /**
31
+ * Factory function type for creating transport instances
32
+ */
33
+ export type TransportFactory = (channel: string) => ITransport;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Inter-tab transport layer with automatic fallback
3
+ *
4
+ * This module provides a unified abstraction for sending and receiving
5
+ * messages between tabs/windows using the best available transport mechanism:
6
+ * - BroadcastChannel API for modern browsers
7
+ * - localStorage with storage events for older browsers
8
+ */
9
+ /**
10
+ * Inter-tab transport with automatic fallback
11
+ *
12
+ * Provides a simple interface for sending and receiving messages
13
+ * between tabs. Automatically selects the best available transport:
14
+ * 1. BroadcastChannel (preferred for modern browsers)
15
+ * 2. localStorage + storage events (fallback for older browsers)
16
+ */
17
+ export declare class InterTabTransport {
18
+ private transport;
19
+ private listeners;
20
+ private unsubscribe?;
21
+ private logger;
22
+ private channelName;
23
+ constructor(channelName?: string);
24
+ /**
25
+ * Send a message to other tabs
26
+ */
27
+ send(message: unknown): void;
28
+ /**
29
+ * Register a message listener
30
+ * @returns Unsubscribe function
31
+ */
32
+ on(listener: (message: unknown) => void): () => void;
33
+ /**
34
+ * Close the transport and clean up resources
35
+ */
36
+ close(): void;
37
+ /**
38
+ * Check if transport is available
39
+ */
40
+ isAvailable(): boolean;
41
+ /**
42
+ * Get the number of registered listeners
43
+ */
44
+ getListenerCount(): number;
45
+ /**
46
+ * Handle incoming messages
47
+ */
48
+ private handleMessage;
49
+ }
@@ -0,0 +1 @@
1
+ import{getLogger as s}from"../core/logger.js";import{createTransport as e}from"./transport-factory.js";class t{constructor(t="fanfare-sdk-sync"){this.transport=null,this.listeners=/* @__PURE__ */new Set,this.logger=s(),this.channelName=t,this.transport=e(t),this.transport?(this.unsubscribe=this.transport.onMessage(s=>{this.handleMessage(s.data)}),this.logger.debug("InterTabTransport initialized",{channelName:t,transportAvailable:this.transport.isAvailable()})):this.logger.debug("No transport available, inter-tab communication disabled")}send(s){if(this.transport)try{this.transport.send(s),this.logger.debug("Message sent via transport",{message:s})}catch(e){this.logger.warn("Failed to send message",{error:e,message:s})}else this.logger.debug("Transport not available, message not sent",{message:s})}on(s){return this.listeners.add(s),this.logger.debug("Transport listener added",{listenerCount:this.listeners.size}),()=>{this.listeners.delete(s),this.logger.debug("Transport listener removed",{listenerCount:this.listeners.size})}}close(){if(this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=void 0),this.transport){try{this.transport.close(),this.logger.debug("Transport closed",{channelName:this.channelName})}catch(s){this.logger.warn("Error closing transport",{error:s})}this.transport=null}this.listeners.clear(),this.logger.debug("Transport closed and listeners cleared")}isAvailable(){return null!==this.transport&&this.transport.isAvailable()}getListenerCount(){return this.listeners.size}handleMessage(s){this.logger.debug("Message received via transport",{message:s,listenerCount:this.listeners.size}),this.listeners.forEach(e=>{try{e(s)}catch(t){this.logger.error("Error in transport listener",{error:t,message:s})}})}}export{t as InterTabTransport};
@@ -0,0 +1,71 @@
1
+ import { MockServer } from './mock-server';
2
+ export type HarnessScenarioKey = "queue" | "waitlist-queue" | "auth-queue" | "access-code-queue" | "queue-denied" | "draw" | "draw-denied" | "timed-release" | "auction" | "auth-draw" | "admission-cycle";
3
+ /**
4
+ * Optional fast-forward marker. When passed on a scenario input, the
5
+ * corresponding distribution mock primes its internal state so the SDK
6
+ * routes straight to the named stage instead of starting at the pre-entry
7
+ * stage. Stages that don't apply to a distribution are ignored.
8
+ *
9
+ * Currently supported per distribution:
10
+ * - queue: "start" (default), "granted"
11
+ * - draw: "start" (default), "granted"
12
+ * - auction: "start" (default), "granted"
13
+ * - timed-release: "start" (default), "granted"
14
+ */
15
+ export type HarnessStage = "start" | "granted";
16
+ export type HarnessScenarioDefinition = {
17
+ key: HarnessScenarioKey;
18
+ label: string;
19
+ experienceId: string;
20
+ sequenceId: string;
21
+ queueId?: string;
22
+ waitlistId?: string;
23
+ accessCode?: string;
24
+ drawId?: string;
25
+ timedReleaseId?: string;
26
+ auctionId?: string;
27
+ stage?: HarnessStage;
28
+ };
29
+ export type HarnessScenarioInput = HarnessScenarioKey | (Partial<HarnessScenarioDefinition> & {
30
+ key: HarnessScenarioKey;
31
+ stage?: HarnessStage;
32
+ });
33
+ export type HarnessRequestLog = {
34
+ api: ReturnType<MockServer["getRequests"]>;
35
+ beacon: ReturnType<MockServer["getRequests"]>;
36
+ };
37
+ export type InstalledHarnessMockServer = {
38
+ apiBaseUrl: string;
39
+ beaconBaseUrl: string;
40
+ /** Primary scenario (first scenario when multiple were installed). */
41
+ scenario: HarnessScenarioDefinition;
42
+ /** All scenarios installed on this server. Always at least one entry. */
43
+ scenarios: HarnessScenarioDefinition[];
44
+ stop: () => void;
45
+ getRequests: () => HarnessRequestLog;
46
+ };
47
+ export type InstallHarnessMockServerOptions = {
48
+ apiBaseUrl?: string;
49
+ beaconBaseUrl?: string;
50
+ defaultDelay?: number;
51
+ logRequests?: boolean;
52
+ otpCode?: string;
53
+ /**
54
+ * Single scenario to install. Mutually exclusive with `scenarios`.
55
+ * If both are absent, defaults to the "queue" scenario.
56
+ */
57
+ scenario?: HarnessScenarioInput;
58
+ /**
59
+ * Multiple scenarios to install on the same mock server. Each scenario's
60
+ * routes are added at their scenario-specific paths (different queueId /
61
+ * drawId / etc. per scenario). Lets one SDK instance render any of the
62
+ * installed experiences without spinning up multiple mock servers.
63
+ */
64
+ scenarios?: HarnessScenarioInput[];
65
+ };
66
+ export declare const DEFAULT_HARNESS_MOCK_API_BASE_URL = "http://mock.local/api";
67
+ export declare const DEFAULT_HARNESS_MOCK_BEACON_BASE_URL = "http://mock.local/beacon";
68
+ export declare const DEFAULT_TEST_OTP_CODE = "424242";
69
+ export declare const HARNESS_SCENARIOS: Record<HarnessScenarioKey, HarnessScenarioDefinition>;
70
+ export declare function normalizeHarnessScenario(input?: HarnessScenarioInput): HarnessScenarioDefinition;
71
+ export declare function installHarnessMockServer(options?: InstallHarnessMockServerOptions): InstalledHarnessMockServer;
@@ -0,0 +1 @@
1
+ import{isMoneyString as e,isMoneyGreaterThan as t,isMoneyGreaterThanOrEqualTo as n}from"../core/money.js";import{MockServer as s,ResponseBuilder as o}from"./mock-server.js";const a="http://mock.local/api",i="http://mock.local/beacon",u="424242";function r(e){const t={isEntered:!1,enteredAt:null};try{const n=window.localStorage.getItem(e);if(!n)return t;const s=JSON.parse(n);return{isEntered:!0===s.isEntered,enteredAt:"string"==typeof s.enteredAt?s.enteredAt:null}}catch{return t}}function d(e,t){window.localStorage.setItem(e,JSON.stringify(t))}const c={queue:{key:"queue",label:"Queue Journey",experienceId:"experience_queue_story_1",sequenceId:"sequence_queue_story_1",queueId:"queue_queue_story_1"},"waitlist-queue":{key:"waitlist-queue",label:"Waitlist to Queue Journey",experienceId:"experience_waitlist_queue_story_1",sequenceId:"sequence_waitlist_queue_story_1",queueId:"queue_waitlist_queue_story_1",waitlistId:"waitlist_waitlist_queue_story_1"},"auth-queue":{key:"auth-queue",label:"Auth-Gated Queue Journey",experienceId:"experience_auth_queue_story_1",sequenceId:"sequence_auth_queue_story_1",queueId:"queue_auth_queue_story_1"},"access-code-queue":{key:"access-code-queue",label:"Access-Code Queue Journey",experienceId:"experience_access_code_queue_story_1",sequenceId:"sequence_access_code_queue_story_1",queueId:"queue_access_code_queue_story_1",accessCode:"VIP123"},draw:{key:"draw",label:"Draw Journey",experienceId:"experience_draw_story_1",sequenceId:"sequence_draw_story_1",drawId:"draw_draw_story_1"},"timed-release":{key:"timed-release",label:"Timed Release Journey",experienceId:"experience_timed_release_story_1",sequenceId:"sequence_timed_release_story_1",timedReleaseId:"timed_release_story_1"},auction:{key:"auction",label:"Auction Journey",experienceId:"experience_auction_story_1",sequenceId:"sequence_auction_story_1",auctionId:"auction_auction_story_1"},"auth-draw":{key:"auth-draw",label:"Auth-Gated Draw Journey",experienceId:"experience_auth_draw_story_1",sequenceId:"sequence_auth_draw_story_1",drawId:"draw_auth_draw_story_1"},"admission-cycle":{key:"admission-cycle",label:"Admission Cycle Journey",experienceId:"experience_admission_cycle_story_1",sequenceId:"sequence_admission_cycle_story_1",queueId:"queue_admission_cycle_story_1"},"queue-denied":{key:"queue-denied",label:"Queue Denied (not selected)",experienceId:"experience_queue_denied_story_1",sequenceId:"sequence_queue_denied_story_1",queueId:"queue_queue_denied_story_1"},"draw-denied":{key:"draw-denied",label:"Draw Denied (not selected)",experienceId:"experience_draw_denied_story_1",sequenceId:"sequence_draw_denied_story_1",drawId:"draw_draw_denied_story_1"}};function _(e){return e.startsWith("http://")||e.startsWith("https://")?e:new URL(e,window.location.origin).toString()}function l(e){if(!e)return c.queue;if("string"==typeof e)return c[e]??c.queue;return{...c[e.key]??c.queue,...e}}async function m(e){try{const t=await e.clone().json();return"object"==typeof t&&null!==t?t:void 0}catch{return}}function I(e,t){return{baseUrl:e,defaultDelay:t.defaultDelay??30,logRequests:t.logRequests??!1,fallbackToNetwork:!1}}function p(e){return function(e){const t=e.headers.get("DPoP"),n=e.headers.get("X-Admission-Key-Thumbprint");if(!t||!n)return!1;const s=t.split(".");return 3===s.length&&!s.some(e=>0===e.length)&&/^[A-Za-z0-9_-]{16,}$/.test(n)}(e)?null:o.badRequest("Missing admission proof headers")}function y(e={}){const t=e.scenarios?.length?e.scenarios.map(e=>l(e)):[l(e.scenario)],n=t[0],d=_(e.apiBaseUrl??a),c=_(e.beaconBaseUrl??i),p=e.otpCode??u,y=new s(I(d,e)),E=new s(I(c,e)),h=/* @__PURE__ */new Date,A=h.toISOString(),x=new Date(h.getTime()+864e5).toISOString(),T={sessionType:null};!function(e,t){const n={id:"session_mock_demo",consumerId:"consumer_mock_demo",guestId:"guest_mock_demo",type:"guest",email:null,phone:null,createdAt:t.nowIso,expiresAt:t.expiresAtIso};e.post("/auth/guest",()=>(t.authState.sessionType="guest",o.ok({session:n,accessToken:"guest_access_token_mock_demo",refreshToken:"guest_refresh_token_mock_demo",beaconToken:"guest_beacon_token_mock_demo"}))),e.post("/auth/refresh",()=>o.ok({accessToken:`access_token_mock_demo_${Date.now()}`,refreshToken:"guest_refresh_token_mock_demo",beaconToken:"authenticated"===t.authState.sessionType?"authenticated_beacon_token_mock_demo":"guest_beacon_token_mock_demo"})),e.post("/auth/otp/request",o.ok({ok:!0})),e.post("/auth/otp/verify",async e=>{const n=await m(e);return("string"==typeof n?.code?n.code:void 0)!==t.otpCode?o.error("Invalid verification code",401):(t.authState.sessionType="authenticated",o.ok({session:{id:"session_authenticated_mock_demo",consumerId:"consumer_authenticated_mock_demo",type:"authenticated",email:"string"==typeof n?.email?n.email:"sdk-harness@example.com",phone:"string"==typeof n?.phone?n.phone:null,createdAt:t.nowIso,expiresAt:t.expiresAtIso},accessToken:"authenticated_access_token_mock_demo",refreshToken:"authenticated_refresh_token_mock_demo",beaconToken:"authenticated_beacon_token_mock_demo"}))}),e.post("/auth/external/exchange",async e=>{const n=await m(e);return("string"==typeof n?.exchangeCode?n.exchangeCode:void 0)?(t.authState.sessionType="authenticated",o.ok({session:{id:"session_external_mock_demo",consumerId:"consumer_external_mock_demo",type:"authenticated",email:"external-auth@example.com",phone:null,createdAt:t.nowIso,expiresAt:t.expiresAtIso},accessToken:"external_access_token_mock_demo",refreshToken:"external_refresh_token_mock_demo",beaconToken:"authenticated_beacon_token_mock_demo"})):o.error("Invalid exchange code",401)})}(y,{nowIso:A,expiresAtIso:x,otpCode:p,authState:T}),function(e){const t=()=>o.ok({ok:!0});e.post("/events",t),e.post("/events/batch",t)}(E);for(const s of t){const e=s.waitlistId?`__fanfare_harness_waitlist__:${s.key}:${s.experienceId}`:void 0,t=s.waitlistId?r(e??""):void 0;k(y,s,{authState:T,expiresAtIso:x,waitlistState:t}),s.queueId&&w(y,{queueId:s.queueId,experienceId:s.experienceId,name:"Journey Queue",initialPosition:"admission-cycle"===s.key?2:5,initialEstimatedWaitSeconds:90,autoExpireAfterGrant:"admission-cycle"===s.key,forceDenyOnEnter:"queue-denied"===s.key}),s.waitlistId&&g(y,{waitlistId:s.waitlistId,sequenceId:s.sequenceId,state:t??{isEntered:!1,enteredAt:null},storageKey:e??""}),s.drawId&&q(y,{drawId:s.drawId,forceDenyOnEnter:"draw-denied"===s.key}),s.timedReleaseId&&D(y,{timedReleaseId:s.timedReleaseId,closeAt:new Date(Date.now()+9e5).toISOString()}),s.auctionId&&S(y,{auctionId:s.auctionId})}return y.start(),E.start(),{apiBaseUrl:d,beaconBaseUrl:c,scenario:n,scenarios:t,stop(){E.stop(),y.stop()},getRequests:()=>({api:y.getRequests(),beacon:E.getRequests()})}}function k(e,t,n){const s=(/* @__PURE__ */new Date).toISOString();e.get("/consumers/me",o.ok({active:{journeys:[]}})),e.get(`/experiences/${t.experienceId}`,o.ok({id:t.experienceId,name:t.label,createdAt:s,updatedAt:s,i18n:{en:{"start.title":t.label,"start.description":"Mock data served from the harness mock server."}}})),e.post(`/experiences/${t.experienceId}/enter`,o.ok({experienceId:t.experienceId,enteredAt:s}));const a=e=>({id:t.sequenceId,name:e,experienceId:t.experienceId,priority:1,color:"#000000"}),i=(e,n,s)=>({schemaVersion:1,experienceId:t.experienceId,outcome:"gated",selected:{sequence:e,status:"gated",gates:[n],reasons:s},offers:[],outcomeReasons:s}),u=e=>({schemaVersion:1,experienceId:t.experienceId,outcome:"routed",selected:{sequence:e,status:"admissible",gates:[],reasons:[],sequenceCapabilityGrant:`mock_sequence_capability_grant_${t.sequenceId}`,sequenceCapabilityGrantExpiresAt:n.expiresAtIso},offers:[],outcomeReasons:[]});"auth-queue"===t.key||"auth-draw"===t.key?e.post(`/experiences/${t.experienceId}/route`,()=>"authenticated"!==n.authState.sessionType?o.ok(i(a("auth-draw"===t.key?"Auth-Gated Draw Sequence":"Auth-Gated Queue Sequence"),{type:"authentication",status:"required",reason:{code:"AUTH_REQUIRED"}},[{code:"AUTH_REQUIRED"}])):o.ok(u(a("auth-draw"===t.key?"Auth-Gated Draw Sequence":"Auth-Gated Queue Sequence")))):"access-code-queue"===t.key?e.post(`/experiences/${t.experienceId}/route`,async e=>{const n=await m(e),s="string"==typeof n?.accessCode?n.accessCode:void 0;return s?s!==t.accessCode?o.ok(i(a("Access-Code Queue Sequence"),{type:"access_code",status:"invalid",reason:{code:"ACCESS_CODE_INVALID"}},[{code:"ACCESS_CODE_INVALID"}])):o.ok(u(a("Access-Code Queue Sequence"))):o.ok(i(a("Access-Code Queue Sequence"),{type:"access_code",status:"missing",reason:{code:"ACCESS_CODE_REQUIRED"}},[{code:"ACCESS_CODE_REQUIRED"}]))}):e.post(`/experiences/${t.experienceId}/route`,o.ok(u(a(`${t.label} Sequence`)))),"waitlist-queue"!==t.key?"draw"!==t.key&&"auth-draw"!==t.key&&"draw-denied"!==t.key?"timed-release"!==t.key?"auction"!==t.key?e.get(`/sequences/${t.sequenceId}/distributions`,()=>{const e=/* @__PURE__ */(new Date).toISOString();return o.ok({recentPast:void 0,active:{type:"queue",id:t.queueId,status:"active",details:{id:t.queueId,type:"queue",openAt:e,metadata:{label:"Journey Queue"},estimatedWaitTime:300,queueLength:10}},upcoming:void 0})}):e.get(`/sequences/${t.sequenceId}/distributions`,()=>{const e=Date.now(),n=new Date(e).toISOString();return o.ok({recentPast:void 0,active:{type:"auction",id:t.auctionId,status:"active",details:{id:t.auctionId,type:"auction",openAt:n,endsAt:new Date(e+36e5).toISOString(),startsAt:n,currencyCode:"USD",reservePrice:"50.00",bidIncrement:"10.00"}},upcoming:void 0})}):e.get(`/sequences/${t.sequenceId}/distributions`,()=>{const e=Date.now();return o.ok({recentPast:void 0,active:{type:"timed_release",id:t.timedReleaseId,status:"active",details:{id:t.timedReleaseId,type:"timed_release",openAt:new Date(e).toISOString(),closeAt:new Date(e+9e5).toISOString()}},upcoming:void 0})}):e.get(`/sequences/${t.sequenceId}/distributions`,()=>{const e=Date.now(),n=new Date(e+72e5).toISOString();return o.ok({recentPast:void 0,active:{type:"draw",id:t.drawId,status:"active",details:{id:t.drawId,type:"draw",openAt:new Date(e).toISOString(),drawTime:n,entryDeadline:n}},upcoming:void 0})}):e.get(`/sequences/${t.sequenceId}/distributions`,()=>{const e=/* @__PURE__ */(new Date).toISOString();return n.waitlistState?.isEntered?o.ok({recentPast:void 0,active:{type:"queue",id:t.queueId,status:"active",details:{id:t.queueId,type:"queue",openAt:e,closeAt:new Date(Date.now()+18e5).toISOString(),metadata:{label:"Journey Queue (Window Open)"},estimatedWaitTime:300,queueLength:10}},upcoming:void 0}):o.ok({recentPast:void 0,active:void 0,upcoming:{type:"queue",id:t.queueId,startsAt:new Date(Date.now()+6e4).toISOString(),waitlistId:t.waitlistId}})})}function w(e,t){const{queueId:n,experienceId:s="experience_mock",name:a="Mock Queue",initialPosition:i=12,initialEstimatedWaitSeconds:u=300,autoExpireAfterGrant:r=!1,forceDenyOnEnter:d=!1}=t;let c=!1,_=!1,l=i,m=u,I=0;e.get(`/queues/${n}`,o.ok({id:n,experienceId:s,name:a,status:"open",capacity:500,currentSize:247,estimatedWaitTime:m,openAt:new Date(Date.now()-3e5).toISOString(),closeAt:new Date(Date.now()+36e5).toISOString()})),e.post(`/queues/${n}/enter`,e=>{const t=p(e);return t||(d?o.ok({status:"DENIED"}):(c=!0,_=!1,I=0,l=i,m=u,o.ok({position:l,estimatedWaitTimeInSeconds:m,status:"QUEUED"})))}),e.post(`/queues/${n}/leave`,()=>(c=!1,_=!1,I=0,o.ok({}))),e.get(`/queues/${n}/status`,()=>c?_?(I+=1,r&&I>1?(c=!1,_=!1,o.ok({status:"EXPIRED"})):o.ok({status:"GRANTED",admissionGrant:`admission_grant_${n}`,expiresAt:new Date(Date.now()+6e5).toISOString()})):(l=Math.max(1,l-1),m=Math.max(0,m-30),l<=1?(_=!0,I=1,o.ok({status:"GRANTED",admissionGrant:`admission_grant_${n}`,expiresAt:new Date(Date.now()+6e5).toISOString()})):o.ok({status:"QUEUED",position:l,estimatedWaitTimeInSeconds:m})):o.ok({status:"NOT_QUEUED"}))}function q(e,t){const{drawId:n,drawAtOffsetMs:s=72e5,forceDenyOnEnter:a=!1}=t;let i="NOT_ENTERED",u=0;e.get(`/draws/${n}`,()=>o.ok({id:n,openAt:new Date(Date.now()-6e4).toISOString(),closeAt:null,timeZone:"UTC",drawAt:new Date(Date.now()+s).toISOString(),capacity:null,continueSelectingUntilCompleted:null})),e.get(`/draws/${n}/status`,()=>"NOT_ENTERED"===i?o.ok({status:"NOT_ENTERED"}):(u+=1,u>=2?o.ok({status:"WON",wonAt:/* @__PURE__ */(new Date).toISOString(),admissionGrant:`admission_grant_${n}`}):o.ok({status:"ENTERED"}))),e.post(`/draws/${n}/enter`,e=>{const t=p(e);return t||(a?o.ok({status:"DENIED"}):(i="ENTERED",u=0,o.ok({status:"ENTERED"})))}),e.post(`/draws/${n}/leave`,()=>(i="NOT_ENTERED",u=0,o.ok({})))}function g(e,t){const{waitlistId:n,sequenceId:s,state:a,storageKey:i}=t;e.get(`/waitlists/${n}/status`,()=>o.ok({waitlistId:n,isEntered:a.isEntered,enteredAt:a.enteredAt??void 0})),e.post(`/waitlists/${n}/enter`,()=>(a.isEntered=!0,a.enteredAt=/* @__PURE__ */(new Date).toISOString(),d(i,a),o.ok({id:`waitlist_entry_${n}`,waitlistId:n,sequenceId:s,consumerId:"consumer_mock_demo",enteredAt:a.enteredAt})));const u=()=>(a.isEntered=!1,a.enteredAt=null,d(i,a),o.ok({}));e.delete(`/waitlists/${n}/leave`,u),e.post(`/waitlists/${n}/leave`,u)}function D(e,t){const{timedReleaseId:n,closeAt:s}=t;let a="NOT_ENTERED",i=null,u=null;e.get(`/timed-releases/${n}`,o.ok({id:n,openAt:new Date(Date.now()-6e4).toISOString(),closeAt:s,timeZone:"America/Los_Angeles",supportsGuest:!0})),e.get(`/timed-releases/${n}/status`,()=>"ENTERED"===a?o.ok({status:"ENTERED",enteredAt:i??/* @__PURE__ */(new Date).toISOString()}):"COMPLETED"===a?o.ok({status:"COMPLETED",completedAt:u??/* @__PURE__ */(new Date).toISOString()}):"LEFT"===a?o.ok({status:"LEFT",leftAt:/* @__PURE__ */(new Date).toISOString()}):o.ok({status:"NOT_ENTERED"})),e.post(`/timed-releases/${n}/enter`,async e=>{const t=await m(e),n="string"==typeof t?.variantId?t.variantId:void 0;return a="ENTERED",i=/* @__PURE__ */(new Date).toISOString(),o.ok({status:"ENTERED",enteredAt:i,selectedVariantId:n})}),e.post(`/timed-releases/${n}/leave`,()=>(a="LEFT",o.ok({}))),e.post(`/timed-releases/${n}/complete`,()=>(a="COMPLETED",u=/* @__PURE__ */(new Date).toISOString(),o.ok({success:!0,admissionGrant:`admission_grant_${n}`})))}function S(s,a){const{auctionId:i}=a,u=/* @__PURE__ */new Date,r=u.toISOString(),d=new Date(u.getTime()+6e5).toISOString();let c="100.00",_=null,l=12,I=!1,p=[{bidId:"bid_1",consumerId:"consumer_mock_demo",amount:"80.00",timestamp:r},{bidId:"bid_2",consumerId:"consumer_mock_demo",amount:"90.00",timestamp:r}];s.get(`/auctions/${i}`,o.ok({id:i,openAt:r,closeAt:d,settleAt:d,currencyCode:"USD",reservePrice:null,minBidIncrement:"10.00",autoExtendSeconds:null,timeZone:"UTC"})),s.get(`/auctions/${i}/highest-bid`,()=>o.ok({amount:c})),s.get(`/auctions/${i}/status`,()=>{const e=null===_?"NOT_BID":n(_,c)?"WINNING":I?"OUTBID":"NOT_BID";return o.ok({status:e,lastBidAmount:_??void 0,bidCount:l,auctionEndTime:d})}),s.post(`/auctions/${i}/enter`,()=>(I=!0,o.ok({}))),s.post(`/auctions/${i}/leave`,()=>(I=!1,_=null,o.ok({}))),s.post(`/auctions/${i}/bid`,async s=>{const a=await m(s),i=a?.amount,u="string"==typeof i?i:"";return e(u)?(_=u,l+=1,t(u,c)&&(c=u),p=[...p,{bidId:`bid_${p.length+1}`,consumerId:"consumer_mock_demo",amount:u,timestamp:/* @__PURE__ */(new Date).toISOString()}],o.ok({status:n(u,c)?"WINNING":"OUTBID",lastBidAmount:u,bidCount:l,winningBidAmount:c,winningBidTime:/* @__PURE__ */(new Date).toISOString(),auctionEndTime:d,paymentToken:null})):o.badRequest("Invalid bid amount")}),s.get(`/auctions/${i}/bids/history`,()=>o.ok(p.map(e=>({...e,isHighest:e.amount===c}))))}export{a as DEFAULT_HARNESS_MOCK_API_BASE_URL,i as DEFAULT_HARNESS_MOCK_BEACON_BASE_URL,u as DEFAULT_TEST_OTP_CODE,c as HARNESS_SCENARIOS,y as installHarnessMockServer,l as normalizeHarnessScenario};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Internal test scaffolding for the first-party adapters (fanfare-sdk-react/
3
+ * -solid), sdk-harness, and Storybook scenarios. NOT customer API and carries
4
+ * no stability guarantee (see docs/PUBLIC_SURFACE.md).
5
+ */
6
+ export * from './harness-scenarios';
7
+ export * from './mock-journey';
8
+ export * from './mock-sdk';
9
+ export * from './mock-server';
10
+ export * from './sdk-factory';
11
+ export * from './verification-scenarios';
12
+ export * from './verification-state';
@@ -0,0 +1 @@
1
+ import{DEFAULT_HARNESS_MOCK_API_BASE_URL as o,DEFAULT_HARNESS_MOCK_BEACON_BASE_URL as r,DEFAULT_TEST_OTP_CODE as m,HARNESS_SCENARIOS as s,installHarnessMockServer as i,normalizeHarnessScenario as t}from"./harness-scenarios.js";import{createMockJourneyHandle as e,createMockJourneyStore as f,makeGatedSnapshot as c,makeReadySnapshot as j,makeRoutedSnapshot as p}from"./mock-journey.js";import{createMockFanfareSDK as a,createMockInternalFanfareSDK as n,mockAuction as k,mockAuctionStatus as v,mockDraw as d,mockDrawStatus as y,mockExperience as h,mockExperienceSession as u,mockQueue as x,mockQueueEnterResult as b,mockQueueStatus as g,mockTimedRelease as l,mockTimedReleaseStatus as q,mockWaitlistEntry as w,mockWaitlistStatus as z}from"./mock-sdk.js";import{MockServer as A,ResponseBuilder as B}from"./mock-server.js";import{createMockSDK as C}from"./sdk-factory.js";import{ADAPTER_SMOKE_SCENARIOS as D,DEFAULT_INVALID_ACCESS_CODE as E,DEFAULT_VALID_ACCESS_CODE as F,DEFAULT_VERIFICATION_EMAIL as G,DEFAULT_VERIFICATION_OTP as H,SDK_VERIFICATION_SCENARIOS as I,SHARED_HARNESS_VERIFICATION_SCENARIOS as J,getVerificationScenario as K,isVerificationScenarioKey as L}from"./verification-scenarios.js";import{resetVerificationState as M}from"./verification-state.js";export{D as ADAPTER_SMOKE_SCENARIOS,o as DEFAULT_HARNESS_MOCK_API_BASE_URL,r as DEFAULT_HARNESS_MOCK_BEACON_BASE_URL,E as DEFAULT_INVALID_ACCESS_CODE,m as DEFAULT_TEST_OTP_CODE,F as DEFAULT_VALID_ACCESS_CODE,G as DEFAULT_VERIFICATION_EMAIL,H as DEFAULT_VERIFICATION_OTP,s as HARNESS_SCENARIOS,A as MockServer,B as ResponseBuilder,I as SDK_VERIFICATION_SCENARIOS,J as SHARED_HARNESS_VERIFICATION_SCENARIOS,a as createMockFanfareSDK,n as createMockInternalFanfareSDK,e as createMockJourneyHandle,f as createMockJourneyStore,C as createMockSDK,K as getVerificationScenario,i as installHarnessMockServer,L as isVerificationScenarioKey,c as makeGatedSnapshot,j as makeReadySnapshot,p as makeRoutedSnapshot,k as mockAuction,v as mockAuctionStatus,d as mockDraw,y as mockDrawStatus,h as mockExperience,u as mockExperienceSession,x as mockQueue,b as mockQueueEnterResult,g as mockQueueStatus,l as mockTimedRelease,q as mockTimedReleaseStatus,w as mockWaitlistEntry,z as mockWaitlistStatus,t as normalizeHarnessScenario,M as resetVerificationState};
@@ -0,0 +1,63 @@
1
+ import { ReadableAtom, WritableAtom } from 'nanostores';
2
+ import { DistributionDisplayState } from '../experiences/distribution-monitor.types';
3
+ import { JourneyViewHandlers } from '../experiences/journey-view';
4
+ import { AdmissionGrant, DistributionSummary, GatedSnapshot, JourneyEvent, JourneyHandle, JourneySnapshot, JourneyView, MechanismConsumerState, ReadySnapshot, RoutedSnapshot, RoutingGate, RoutingOffer, SequenceOutcome, SequenceState } from '../experiences/journey.types';
5
+ export declare function makeReadySnapshot(experienceId?: string, overrides?: Partial<ReadySnapshot>): ReadySnapshot;
6
+ export declare function makeGatedSnapshot(params?: {
7
+ experienceId?: string;
8
+ gates?: RoutingGate[];
9
+ selected?: GatedSnapshot["selected"];
10
+ overrides?: Partial<GatedSnapshot>;
11
+ }): GatedSnapshot;
12
+ export declare function makeRoutedSnapshot(params: {
13
+ sequence?: SequenceState | ({
14
+ phase: SequenceState["phase"];
15
+ waitlistId?: string;
16
+ reason?: string;
17
+ } & Record<string, unknown>);
18
+ experienceId?: string;
19
+ sequenceId?: string;
20
+ offers?: RoutingOffer[];
21
+ distribution?: DistributionSummary;
22
+ consumer?: MechanismConsumerState;
23
+ grant?: AdmissionGrant;
24
+ outcome?: SequenceOutcome;
25
+ overrides?: Partial<RoutedSnapshot> & {
26
+ consumer?: MechanismConsumerState;
27
+ grant?: AdmissionGrant;
28
+ outcome?: SequenceOutcome;
29
+ actions?: unknown;
30
+ };
31
+ }): RoutedSnapshot;
32
+ export interface MockJourneyStore {
33
+ atom: WritableAtom<JourneySnapshot>;
34
+ get(): JourneySnapshot;
35
+ listen(listener: (value: JourneySnapshot, oldValue?: JourneySnapshot) => void): () => void;
36
+ subscribe(listener: (value: JourneySnapshot, oldValue?: JourneySnapshot) => void): () => void;
37
+ setValue(value: JourneySnapshot): void;
38
+ getListenerCount(): number;
39
+ }
40
+ export declare function createMockJourneyStore(initial?: JourneySnapshot): MockJourneyStore;
41
+ export interface MockJourneyController {
42
+ handle: JourneyHandle;
43
+ snapshot$: MockJourneyStore;
44
+ view$: ReadableAtom<JourneyView>;
45
+ events$: ReadableAtom<JourneyEvent[]>;
46
+ latestEvent$: ReadableAtom<JourneyEvent | null>;
47
+ handlers: JourneyViewHandlers;
48
+ setSnapshot(value: JourneySnapshot): void;
49
+ updateSnapshot(updater: (value: JourneySnapshot) => JourneySnapshot): void;
50
+ setDisplayState(value: DistributionDisplayState): void;
51
+ ackEvent(eventId: string): void;
52
+ ackAllEvents(): void;
53
+ destroy(): void;
54
+ }
55
+ export declare function createMockJourneyHandle(args?: {
56
+ initialSnapshot?: JourneySnapshot;
57
+ handlers?: Partial<JourneyViewHandlers>;
58
+ actions?: Partial<JourneyViewHandlers & {
59
+ ackEvent(eventId: string): void;
60
+ ackAllEvents(): void;
61
+ destroy(): void;
62
+ }>;
63
+ }): MockJourneyController;
@@ -0,0 +1 @@
1
+ import{atom as e,computed as t}from"nanostores";import{buildJourneyView as n}from"../experiences/journey-view.js";import{deriveSequenceState as s}from"../experiences/journey.machine.js";function r(e){if("routed"!==e.journeyStage||"participating"!==e.sequence.phase)return{type:"queue"};switch(e.sequence.mechanism){case"queue":case"waitlist":return{type:"queue"};case"draw":return{type:"draw"};case"auction":return{type:"auction"};case"timed_release":return{type:"timed_release"};case"appointment":return{type:"appointment"}}}function a(e="exp_123",t){return{revision:1,updatedAt:Date.now(),journeyStage:"ready",experienceId:e,experience:void 0,events:[],lastSeenEventId:void 0,...t}}function o(e){return{...a(e?.experienceId),journeyStage:"gated",gates:e?.gates??[],selected:e?.selected,...e?.overrides}}function c(e){const t=e.sequence&&"mechanism"in e.sequence?e.sequence:s({distribution:e.distribution,consumer:e.consumer??e.overrides?.consumer,grant:e.grant??e.overrides?.grant,outcome:e.outcome??e.overrides?.outcome}),{consumer:n,grant:r,outcome:o,actions:c,sequence:i,...u}=e.overrides??{};return{...a(e.experienceId),journeyStage:"routed",sequenceId:e.sequenceId??"seq_1",offers:e.offers??[],sequence:t,...u}}function i(t){const n=e(t??a());let s=0;return{atom:n,get:()=>n.get(),listen:e=>{s+=1;const t=n.listen(e);return()=>{s-=1,t()}},subscribe:e=>{s+=1;const t=n.subscribe(e);return()=>{s-=1,t()}},setValue:e=>n.set(e),getListenerCount:()=>s}}function u(s){const o=s?.initialSnapshot??a(),c=i(o),u=e(r(c.get())),d=s?.actions??{},l={start:async()=>{},reroute:async()=>{},retry:async()=>{},enter:async()=>{},leave:async()=>{},bid:async()=>{},complete:async()=>{},book:async()=>{},cancel:async()=>{},reschedule:async()=>{},claim:()=>{const e=c.get();if("routed"===e.journeyStage&&"granted"===e.sequence.phase)return e.sequence.grant;throw new Error("No grant is available to claim")},...s?.handlers,...d},v=t(c.atom,e=>n(e,l,u)),p=t(c.atom,e=>e.events),m=t(c.atom,e=>{if(!e.events.length)return null;const t=e.lastSeenEventId??"",n=e.events.filter(e=>e.id>t);return n.length?n[n.length-1]:null}),y=e=>{if(d.ackEvent)return void d.ackEvent(e);const t=c.get();t.events.some(t=>t.id===e)&&c.setValue({...t,lastSeenEventId:e})},g=()=>{if(d.ackAllEvents)return void d.ackAllEvents();const e=c.get(),t=e.events[e.events.length-1];t&&c.setValue({...e,lastSeenEventId:t.id})},f=()=>{if(d.destroy)return void d.destroy();const e=c.get().experienceId||o.experienceId;c.setValue(a(e)),u.set(r(a(e)))};return{handle:{view$:v,snapshot$:c.atom,events$:p,latestEvent$:m,ackEvent:y,ackAllEvents:g,destroy:f},snapshot$:c,view$:v,events$:p,latestEvent$:m,handlers:l,setSnapshot:e=>{c.setValue(e)},updateSnapshot:e=>{const t=e(c.get());c.setValue(t)},setDisplayState:e=>u.set(e),ackEvent:y,ackAllEvents:g,destroy:f}}export{u as createMockJourneyHandle,i as createMockJourneyStore,o as makeGatedSnapshot,a as makeReadySnapshot,c as makeRoutedSnapshot};