@getuserfeedback/protocol 3.0.7 → 3.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attention-policy.d.ts +28 -0
- package/dist/attention-policy.d.ts.map +1 -0
- package/dist/attention-policy.js +18 -0
- package/dist/flow-display.d.ts +16 -0
- package/dist/flow-display.d.ts.map +1 -1
- package/dist/flow-display.js +2 -0
- package/dist/host/widget-layout-size-update.d.ts +31 -2
- package/dist/host/widget-layout-size-update.d.ts.map +1 -1
- package/dist/host/widget-layout-size-update.js +40 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +1 -1
- package/src/attention-policy.ts +27 -0
- package/src/flow-display.test.ts +1 -0
- package/src/flow-display.ts +6 -0
- package/src/host/widget-layout-size-update.test.ts +65 -0
- package/src/host/widget-layout-size-update.ts +85 -2
- package/src/index.ts +8 -0
- package/src/protocol-root.test.ts +14 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
export declare const attentionPolicySourceSchema: z.ZodMiniEnum<{
|
|
3
|
+
default: "default";
|
|
4
|
+
custom: "custom";
|
|
5
|
+
}>;
|
|
6
|
+
export declare const attentionExclusiveSurfaceStrategySchema: z.ZodMiniEnum<{
|
|
7
|
+
queue: "queue";
|
|
8
|
+
}>;
|
|
9
|
+
export declare const attentionBlockedBroadcastStrategySchema: z.ZodMiniEnum<{
|
|
10
|
+
queue: "queue";
|
|
11
|
+
}>;
|
|
12
|
+
export declare const attentionPolicyConfigSchema: z.ZodMiniObject<{
|
|
13
|
+
version: z.ZodMiniString<string>;
|
|
14
|
+
source: z.ZodMiniEnum<{
|
|
15
|
+
default: "default";
|
|
16
|
+
custom: "custom";
|
|
17
|
+
}>;
|
|
18
|
+
recentFlowCooldownMs: z.ZodMiniNumber<number>;
|
|
19
|
+
exclusiveSurfaceStrategy: z.ZodMiniEnum<{
|
|
20
|
+
queue: "queue";
|
|
21
|
+
}>;
|
|
22
|
+
blockedBroadcastStrategy: z.ZodMiniEnum<{
|
|
23
|
+
queue: "queue";
|
|
24
|
+
}>;
|
|
25
|
+
}, z.core.$strict>;
|
|
26
|
+
export type AttentionPolicyConfig = z.output<typeof attentionPolicyConfigSchema>;
|
|
27
|
+
export declare const DEFAULT_ATTENTION_POLICY_CONFIG: AttentionPolicyConfig;
|
|
28
|
+
//# sourceMappingURL=attention-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attention-policy.d.ts","sourceRoot":"","sources":["../src/attention-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,eAAO,MAAM,2BAA2B;;;EAAgC,CAAC;AAEzE,eAAO,MAAM,uCAAuC;;EAAoB,CAAC;AAEzE,eAAO,MAAM,uCAAuC;;EAAoB,CAAC;AAEzE,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;kBAMtC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAC3C,OAAO,2BAA2B,CAClC,CAAC;AAEF,eAAO,MAAM,+BAA+B,EAAE,qBAM7C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
export const attentionPolicySourceSchema = z.enum(["default", "custom"]);
|
|
3
|
+
export const attentionExclusiveSurfaceStrategySchema = z.enum(["queue"]);
|
|
4
|
+
export const attentionBlockedBroadcastStrategySchema = z.enum(["queue"]);
|
|
5
|
+
export const attentionPolicyConfigSchema = z.strictObject({
|
|
6
|
+
version: z.string().check(z.trim(), z.minLength(1)),
|
|
7
|
+
source: attentionPolicySourceSchema,
|
|
8
|
+
recentFlowCooldownMs: z.number().check(z.positive()),
|
|
9
|
+
exclusiveSurfaceStrategy: attentionExclusiveSurfaceStrategySchema,
|
|
10
|
+
blockedBroadcastStrategy: attentionBlockedBroadcastStrategySchema,
|
|
11
|
+
});
|
|
12
|
+
export const DEFAULT_ATTENTION_POLICY_CONFIG = {
|
|
13
|
+
version: "attention-policy-default-v1",
|
|
14
|
+
source: "default",
|
|
15
|
+
recentFlowCooldownMs: 5 * 60 * 1000,
|
|
16
|
+
exclusiveSurfaceStrategy: "queue",
|
|
17
|
+
blockedBroadcastStrategy: "queue",
|
|
18
|
+
};
|
package/dist/flow-display.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as z from "zod/mini";
|
|
2
|
+
import { type AttentionPolicyConfig } from "./attention-policy.js";
|
|
2
3
|
export declare const runtimeDisplayEligibilitySchema: z.ZodMiniObject<{
|
|
3
4
|
requiredCapabilities: z.ZodMiniDefault<z.ZodMiniArray<z.ZodMiniString<string>>>;
|
|
4
5
|
requiredPage: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
@@ -199,6 +200,20 @@ export declare const flowDisplaySyncRequestSchema: z.ZodMiniObject<{
|
|
|
199
200
|
}, z.core.$strip>;
|
|
200
201
|
export declare const flowDisplaySyncResponseSchema: z.ZodMiniObject<{
|
|
201
202
|
fetchedAt: z.ZodMiniString<string>;
|
|
203
|
+
attentionPolicy: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
204
|
+
version: z.ZodMiniString<string>;
|
|
205
|
+
source: z.ZodMiniEnum<{
|
|
206
|
+
default: "default";
|
|
207
|
+
custom: "custom";
|
|
208
|
+
}>;
|
|
209
|
+
recentFlowCooldownMs: z.ZodMiniNumber<number>;
|
|
210
|
+
exclusiveSurfaceStrategy: z.ZodMiniEnum<{
|
|
211
|
+
queue: "queue";
|
|
212
|
+
}>;
|
|
213
|
+
blockedBroadcastStrategy: z.ZodMiniEnum<{
|
|
214
|
+
queue: "queue";
|
|
215
|
+
}>;
|
|
216
|
+
}, z.core.$strict>>;
|
|
202
217
|
assignments: z.ZodMiniObject<{
|
|
203
218
|
claimed: z.ZodMiniArray<z.ZodMiniObject<{
|
|
204
219
|
flowAssignmentId: z.ZodMiniString<string>;
|
|
@@ -272,4 +287,5 @@ export type RuntimeDisplayEligibility = z.output<typeof runtimeDisplayEligibilit
|
|
|
272
287
|
export type RuntimeDisplayTrigger = z.output<typeof runtimeDisplayTriggerSchema>;
|
|
273
288
|
export type FlowDisplaySyncRequest = z.output<typeof flowDisplaySyncRequestSchema>;
|
|
274
289
|
export type FlowDisplaySyncResponse = z.output<typeof flowDisplaySyncResponseSchema>;
|
|
290
|
+
export type FlowDisplayAttentionPolicyConfig = AttentionPolicyConfig;
|
|
275
291
|
//# sourceMappingURL=flow-display.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-display.d.ts","sourceRoot":"","sources":["../src/flow-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"flow-display.d.ts","sourceRoot":"","sources":["../src/flow-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,OAAO,EACN,KAAK,qBAAqB,EAE1B,MAAM,uBAAuB,CAAC;AAO/B,eAAO,MAAM,+BAA+B;;;;;iBAU1C,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;2BAOtC,CAAC;AAQH,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;iBAY9C,CAAC;AAEH,eAAO,MAAM,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAenD,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGzC,CAAC;AAEH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBASvC,CAAC;AAEH,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAOxC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAC9C,OAAO,8BAA8B,CACrC,CAAC;AACF,MAAM,MAAM,kCAAkC,GAAG,CAAC,CAAC,MAAM,CACxD,OAAO,wCAAwC,CAC/C,CAAC;AACF,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CACnD,OAAO,mCAAmC,CAC1C,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAC/C,OAAO,+BAA+B,CACtC,CAAC;AACF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAC3C,OAAO,2BAA2B,CAClC,CAAC;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAC5C,OAAO,4BAA4B,CACnC,CAAC;AACF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAC7C,OAAO,6BAA6B,CACpC,CAAC;AACF,MAAM,MAAM,gCAAgC,GAAG,qBAAqB,CAAC"}
|
package/dist/flow-display.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as z from "zod/mini";
|
|
2
|
+
import { attentionPolicyConfigSchema, } from "./attention-policy.js";
|
|
2
3
|
import { flowAssignmentIdentitySchema, flowAssignmentRecordSchema, flowAssignmentTargetingContextSchema, } from "./flow-assignments.js";
|
|
3
4
|
export const runtimeDisplayEligibilitySchema = z.object({
|
|
4
5
|
requiredCapabilities: z._default(z.array(z.string().check(z.trim(), z.minLength(1))), []),
|
|
@@ -55,6 +56,7 @@ export const flowDisplaySyncRequestSchema = z.object({
|
|
|
55
56
|
});
|
|
56
57
|
export const flowDisplaySyncResponseSchema = z.object({
|
|
57
58
|
fetchedAt: z.string(),
|
|
59
|
+
attentionPolicy: z.optional(attentionPolicyConfigSchema),
|
|
58
60
|
assignments: z.object({
|
|
59
61
|
claimed: z.array(flowAssignmentRecordSchema),
|
|
60
62
|
}),
|
|
@@ -2,14 +2,43 @@ export type WidgetLayoutSize = {
|
|
|
2
2
|
width: number;
|
|
3
3
|
height: number;
|
|
4
4
|
};
|
|
5
|
-
export type
|
|
5
|
+
export type WidgetLayoutCubicBezier = readonly [
|
|
6
|
+
x1: number,
|
|
7
|
+
y1: number,
|
|
8
|
+
x2: number,
|
|
9
|
+
y2: number
|
|
10
|
+
];
|
|
11
|
+
export type WidgetLayoutInstantSizeTransition = {
|
|
6
12
|
kind: "instant";
|
|
7
13
|
durationMs: 0;
|
|
8
14
|
};
|
|
15
|
+
export type WidgetLayoutTimedSizeTransition = {
|
|
16
|
+
kind: "timed";
|
|
17
|
+
durationMs: number;
|
|
18
|
+
easing: {
|
|
19
|
+
kind: "cubic-bezier";
|
|
20
|
+
points: WidgetLayoutCubicBezier;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export type WidgetLayoutSizeTransition = WidgetLayoutInstantSizeTransition;
|
|
9
24
|
export type WidgetLayoutSizeUpdate = {
|
|
10
25
|
size: WidgetLayoutSize;
|
|
11
26
|
transition: WidgetLayoutSizeTransition;
|
|
12
27
|
};
|
|
13
|
-
export
|
|
28
|
+
export type WidgetLayoutTimedSizeUpdate = {
|
|
29
|
+
size: WidgetLayoutSize;
|
|
30
|
+
transition: WidgetLayoutTimedSizeTransition;
|
|
31
|
+
};
|
|
32
|
+
export declare const INSTANT_WIDGET_LAYOUT_SIZE_TRANSITION: WidgetLayoutInstantSizeTransition;
|
|
33
|
+
export declare function isWidgetLayoutCubicBezier(points: unknown): points is WidgetLayoutCubicBezier;
|
|
14
34
|
export declare function toInstantWidgetLayoutSizeUpdate(size: WidgetLayoutSize): WidgetLayoutSizeUpdate;
|
|
35
|
+
export declare function toTimedWidgetLayoutSizeTransition(input: {
|
|
36
|
+
durationMs: number;
|
|
37
|
+
easing: WidgetLayoutCubicBezier;
|
|
38
|
+
}): WidgetLayoutTimedSizeTransition;
|
|
39
|
+
export declare function toTimedWidgetLayoutSizeUpdate(input: {
|
|
40
|
+
size: WidgetLayoutSize;
|
|
41
|
+
durationMs: number;
|
|
42
|
+
easing: WidgetLayoutCubicBezier;
|
|
43
|
+
}): WidgetLayoutTimedSizeUpdate;
|
|
15
44
|
//# sourceMappingURL=widget-layout-size-update.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widget-layout-size-update.d.ts","sourceRoot":"","sources":["../../src/host/widget-layout-size-update.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"widget-layout-size-update.d.ts","sourceRoot":"","sources":["../../src/host/widget-layout-size-update.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,SAAS;IAC9C,EAAE,EAAE,MAAM;IACV,EAAE,EAAE,MAAM;IACV,EAAE,EAAE,MAAM;IACV,EAAE,EAAE,MAAM;CACV,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG;IAC/C,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,CAAC,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC7C,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE;QACP,IAAI,EAAE,cAAc,CAAC;QACrB,MAAM,EAAE,uBAAuB,CAAC;KAChC,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,iCAAiC,CAAC;AAE3E,MAAM,MAAM,sBAAsB,GAAG;IACpC,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,0BAA0B,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACzC,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,+BAA+B,CAAC;CAC5C,CAAC;AAEF,eAAO,MAAM,qCAAqC,EAAE,iCAIlD,CAAC;AAKH,wBAAgB,yBAAyB,CACxC,MAAM,EAAE,OAAO,GACb,MAAM,IAAI,uBAAuB,CAenC;AAED,wBAAgB,+BAA+B,CAC9C,IAAI,EAAE,gBAAgB,GACpB,sBAAsB,CAKxB;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,uBAAuB,CAAC;CAChC,GAAG,+BAA+B,CAmBlC;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACpD,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,uBAAuB,CAAC;CAChC,GAAG,2BAA2B,CAQ9B"}
|
|
@@ -2,9 +2,49 @@ export const INSTANT_WIDGET_LAYOUT_SIZE_TRANSITION = {
|
|
|
2
2
|
kind: "instant",
|
|
3
3
|
durationMs: 0,
|
|
4
4
|
};
|
|
5
|
+
const isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
6
|
+
export function isWidgetLayoutCubicBezier(points) {
|
|
7
|
+
if (!Array.isArray(points) || points.length !== 4) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const [x1, y1, x2, y2] = points;
|
|
11
|
+
return (isFiniteNumber(x1) &&
|
|
12
|
+
x1 >= 0 &&
|
|
13
|
+
x1 <= 1 &&
|
|
14
|
+
isFiniteNumber(y1) &&
|
|
15
|
+
isFiniteNumber(x2) &&
|
|
16
|
+
x2 >= 0 &&
|
|
17
|
+
x2 <= 1 &&
|
|
18
|
+
isFiniteNumber(y2));
|
|
19
|
+
}
|
|
5
20
|
export function toInstantWidgetLayoutSizeUpdate(size) {
|
|
6
21
|
return {
|
|
7
22
|
size: { ...size },
|
|
8
23
|
transition: INSTANT_WIDGET_LAYOUT_SIZE_TRANSITION,
|
|
9
24
|
};
|
|
10
25
|
}
|
|
26
|
+
export function toTimedWidgetLayoutSizeTransition(input) {
|
|
27
|
+
if (!Number.isFinite(input.durationMs) || input.durationMs <= 0) {
|
|
28
|
+
throw new RangeError("Timed widget layout transitions require durationMs > 0");
|
|
29
|
+
}
|
|
30
|
+
if (!isWidgetLayoutCubicBezier(input.easing)) {
|
|
31
|
+
throw new RangeError("Timed widget layout transitions require cubic-bezier x control points in [0, 1] and finite y control points");
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
kind: "timed",
|
|
35
|
+
durationMs: input.durationMs,
|
|
36
|
+
easing: {
|
|
37
|
+
kind: "cubic-bezier",
|
|
38
|
+
points: [...input.easing],
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function toTimedWidgetLayoutSizeUpdate(input) {
|
|
43
|
+
return {
|
|
44
|
+
size: { ...input.size },
|
|
45
|
+
transition: toTimedWidgetLayoutSizeTransition({
|
|
46
|
+
durationMs: input.durationMs,
|
|
47
|
+
easing: input.easing,
|
|
48
|
+
}),
|
|
49
|
+
};
|
|
50
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { type AppEventCapability, type AppEventExternalId, type AppEventFlag, type AppEventJsonValue, type AppEventPayload, type AppEventTrackInput, appEventBaseSchema, appEventCapabilitySchema, appEventContextSchema, appEventCustomerTrackSchema, appEventExternalIdSchema, appEventFlagProviderSchema, appEventFlagSchema, appEventFlowDismissedSchema, appEventIdentitySchema, appEventIdentityTypeSchema, appEventPayloadSchema, appEventSurveyViewedSchema, appEventSystemBaseSchema, appEventSystemTrackSchema, appEventTrackSchema, reservedSystemAppEventNames, } from "./app-event.js";
|
|
2
|
+
export { type AttentionPolicyConfig, attentionBlockedBroadcastStrategySchema, attentionExclusiveSurfaceStrategySchema, attentionPolicyConfigSchema, attentionPolicySourceSchema, DEFAULT_ATTENTION_POLICY_CONFIG, } from "./attention-policy.js";
|
|
2
3
|
export { type ClientMeta, clientMetaSchema, } from "./client-meta.js";
|
|
3
4
|
export { type CommandContext, type CoreCommandEnvelope, coreCommandEnvelopeSchema, } from "./core-command-envelope.js";
|
|
4
5
|
export { type CoreCommandPayload, coreCommandPayloadSchema, } from "./core-commands.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { appEventBaseSchema, appEventCapabilitySchema, appEventContextSchema, appEventCustomerTrackSchema, appEventExternalIdSchema, appEventFlagProviderSchema, appEventFlagSchema, appEventFlowDismissedSchema, appEventIdentitySchema, appEventIdentityTypeSchema, appEventPayloadSchema, appEventSurveyViewedSchema, appEventSystemBaseSchema, appEventSystemTrackSchema, appEventTrackSchema, reservedSystemAppEventNames, } from "./app-event.js";
|
|
2
|
+
export { attentionBlockedBroadcastStrategySchema, attentionExclusiveSurfaceStrategySchema, attentionPolicyConfigSchema, attentionPolicySourceSchema, DEFAULT_ATTENTION_POLICY_CONFIG, } from "./attention-policy.js";
|
|
2
3
|
export { clientMetaSchema, } from "./client-meta.js";
|
|
3
4
|
export { coreCommandEnvelopeSchema, } from "./core-command-envelope.js";
|
|
4
5
|
export { coreCommandPayloadSchema, } from "./core-commands.js";
|
package/package.json
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
|
|
3
|
+
export const attentionPolicySourceSchema = z.enum(["default", "custom"]);
|
|
4
|
+
|
|
5
|
+
export const attentionExclusiveSurfaceStrategySchema = z.enum(["queue"]);
|
|
6
|
+
|
|
7
|
+
export const attentionBlockedBroadcastStrategySchema = z.enum(["queue"]);
|
|
8
|
+
|
|
9
|
+
export const attentionPolicyConfigSchema = z.strictObject({
|
|
10
|
+
version: z.string().check(z.trim(), z.minLength(1)),
|
|
11
|
+
source: attentionPolicySourceSchema,
|
|
12
|
+
recentFlowCooldownMs: z.number().check(z.positive()),
|
|
13
|
+
exclusiveSurfaceStrategy: attentionExclusiveSurfaceStrategySchema,
|
|
14
|
+
blockedBroadcastStrategy: attentionBlockedBroadcastStrategySchema,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export type AttentionPolicyConfig = z.output<
|
|
18
|
+
typeof attentionPolicyConfigSchema
|
|
19
|
+
>;
|
|
20
|
+
|
|
21
|
+
export const DEFAULT_ATTENTION_POLICY_CONFIG: AttentionPolicyConfig = {
|
|
22
|
+
version: "attention-policy-default-v1",
|
|
23
|
+
source: "default",
|
|
24
|
+
recentFlowCooldownMs: 5 * 60 * 1000,
|
|
25
|
+
exclusiveSurfaceStrategy: "queue",
|
|
26
|
+
blockedBroadcastStrategy: "queue",
|
|
27
|
+
};
|
package/src/flow-display.test.ts
CHANGED
|
@@ -52,6 +52,7 @@ describe("flow display sync contracts", () => {
|
|
|
52
52
|
|
|
53
53
|
expect(result.assignments.claimed[0]?.flowAssignmentId).toBe("fa_1");
|
|
54
54
|
expect(result.broadcasts.opportunities).toEqual([]);
|
|
55
|
+
expect(result.attentionPolicy).toBeUndefined();
|
|
55
56
|
});
|
|
56
57
|
|
|
57
58
|
it("accepts runtime broadcast opportunities", () => {
|
package/src/flow-display.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import * as z from "zod/mini";
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
type AttentionPolicyConfig,
|
|
5
|
+
attentionPolicyConfigSchema,
|
|
6
|
+
} from "./attention-policy.js";
|
|
3
7
|
import {
|
|
4
8
|
flowAssignmentIdentitySchema,
|
|
5
9
|
flowAssignmentRecordSchema,
|
|
@@ -82,6 +86,7 @@ export const flowDisplaySyncRequestSchema = z.object({
|
|
|
82
86
|
|
|
83
87
|
export const flowDisplaySyncResponseSchema = z.object({
|
|
84
88
|
fetchedAt: z.string(),
|
|
89
|
+
attentionPolicy: z.optional(attentionPolicyConfigSchema),
|
|
85
90
|
assignments: z.object({
|
|
86
91
|
claimed: z.array(flowAssignmentRecordSchema),
|
|
87
92
|
}),
|
|
@@ -109,3 +114,4 @@ export type FlowDisplaySyncRequest = z.output<
|
|
|
109
114
|
export type FlowDisplaySyncResponse = z.output<
|
|
110
115
|
typeof flowDisplaySyncResponseSchema
|
|
111
116
|
>;
|
|
117
|
+
export type FlowDisplayAttentionPolicyConfig = AttentionPolicyConfig;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
import {
|
|
3
3
|
INSTANT_WIDGET_LAYOUT_SIZE_TRANSITION,
|
|
4
|
+
isWidgetLayoutCubicBezier,
|
|
4
5
|
toInstantWidgetLayoutSizeUpdate,
|
|
6
|
+
toTimedWidgetLayoutSizeTransition,
|
|
7
|
+
toTimedWidgetLayoutSizeUpdate,
|
|
5
8
|
} from "./widget-layout-size-update.js";
|
|
6
9
|
|
|
7
10
|
describe("widget layout size update", () => {
|
|
@@ -22,4 +25,66 @@ describe("widget layout size update", () => {
|
|
|
22
25
|
toInstantWidgetLayoutSizeUpdate({ width: 1, height: 1 }).transition,
|
|
23
26
|
).toBe(INSTANT_WIDGET_LAYOUT_SIZE_TRANSITION);
|
|
24
27
|
});
|
|
28
|
+
|
|
29
|
+
test("keeps the existing size update contract instant-only", () => {
|
|
30
|
+
const update = toInstantWidgetLayoutSizeUpdate({ width: 320, height: 240 });
|
|
31
|
+
|
|
32
|
+
expect(update.transition.kind).toBe("instant");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("wraps a host size in the timed transition contract", () => {
|
|
36
|
+
expect(
|
|
37
|
+
toTimedWidgetLayoutSizeUpdate({
|
|
38
|
+
size: { width: 320, height: 240 },
|
|
39
|
+
durationMs: 180,
|
|
40
|
+
easing: [0.2, 0, 0, 1],
|
|
41
|
+
}),
|
|
42
|
+
).toEqual({
|
|
43
|
+
size: { width: 320, height: 240 },
|
|
44
|
+
transition: {
|
|
45
|
+
kind: "timed",
|
|
46
|
+
durationMs: 180,
|
|
47
|
+
easing: {
|
|
48
|
+
kind: "cubic-bezier",
|
|
49
|
+
points: [0.2, 0, 0, 1],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("accepts cubic-bezier y control point overshoot", () => {
|
|
56
|
+
expect(isWidgetLayoutCubicBezier([0.34, -0.2, 0.64, 1.35])).toBe(true);
|
|
57
|
+
expect(
|
|
58
|
+
toTimedWidgetLayoutSizeTransition({
|
|
59
|
+
durationMs: 220,
|
|
60
|
+
easing: [0.34, -0.2, 0.64, 1.35],
|
|
61
|
+
}).easing.points,
|
|
62
|
+
).toEqual([0.34, -0.2, 0.64, 1.35]);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("fails closed for non-array cubic-bezier input", () => {
|
|
66
|
+
expect(isWidgetLayoutCubicBezier(null)).toBe(false);
|
|
67
|
+
expect(isWidgetLayoutCubicBezier({ 0: 0.2, 1: 0, 2: 0, 3: 1 })).toBe(false);
|
|
68
|
+
expect(isWidgetLayoutCubicBezier("0.2,0,0,1")).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test("rejects cubic-bezier x control points outside normalized time", () => {
|
|
72
|
+
expect(isWidgetLayoutCubicBezier([-0.01, 0, 0.5, 1])).toBe(false);
|
|
73
|
+
expect(isWidgetLayoutCubicBezier([0.5, 0, 1.01, 1])).toBe(false);
|
|
74
|
+
expect(() =>
|
|
75
|
+
toTimedWidgetLayoutSizeTransition({
|
|
76
|
+
durationMs: 220,
|
|
77
|
+
easing: [-0.01, 0, 0.5, 1],
|
|
78
|
+
}),
|
|
79
|
+
).toThrow(RangeError);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("rejects invalid timed transition duration", () => {
|
|
83
|
+
expect(() =>
|
|
84
|
+
toTimedWidgetLayoutSizeTransition({
|
|
85
|
+
durationMs: 0,
|
|
86
|
+
easing: [0.2, 0, 0, 1],
|
|
87
|
+
}),
|
|
88
|
+
).toThrow(RangeError);
|
|
89
|
+
});
|
|
25
90
|
});
|
|
@@ -3,22 +3,67 @@ export type WidgetLayoutSize = {
|
|
|
3
3
|
height: number;
|
|
4
4
|
};
|
|
5
5
|
|
|
6
|
-
export type
|
|
6
|
+
export type WidgetLayoutCubicBezier = readonly [
|
|
7
|
+
x1: number,
|
|
8
|
+
y1: number,
|
|
9
|
+
x2: number,
|
|
10
|
+
y2: number,
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
export type WidgetLayoutInstantSizeTransition = {
|
|
7
14
|
kind: "instant";
|
|
8
15
|
durationMs: 0;
|
|
9
16
|
};
|
|
10
17
|
|
|
18
|
+
export type WidgetLayoutTimedSizeTransition = {
|
|
19
|
+
kind: "timed";
|
|
20
|
+
durationMs: number;
|
|
21
|
+
easing: {
|
|
22
|
+
kind: "cubic-bezier";
|
|
23
|
+
points: WidgetLayoutCubicBezier;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type WidgetLayoutSizeTransition = WidgetLayoutInstantSizeTransition;
|
|
28
|
+
|
|
11
29
|
export type WidgetLayoutSizeUpdate = {
|
|
12
30
|
size: WidgetLayoutSize;
|
|
13
31
|
transition: WidgetLayoutSizeTransition;
|
|
14
32
|
};
|
|
15
33
|
|
|
16
|
-
export
|
|
34
|
+
export type WidgetLayoutTimedSizeUpdate = {
|
|
35
|
+
size: WidgetLayoutSize;
|
|
36
|
+
transition: WidgetLayoutTimedSizeTransition;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const INSTANT_WIDGET_LAYOUT_SIZE_TRANSITION: WidgetLayoutInstantSizeTransition =
|
|
17
40
|
{
|
|
18
41
|
kind: "instant",
|
|
19
42
|
durationMs: 0,
|
|
20
43
|
};
|
|
21
44
|
|
|
45
|
+
const isFiniteNumber = (value: unknown): value is number =>
|
|
46
|
+
typeof value === "number" && Number.isFinite(value);
|
|
47
|
+
|
|
48
|
+
export function isWidgetLayoutCubicBezier(
|
|
49
|
+
points: unknown,
|
|
50
|
+
): points is WidgetLayoutCubicBezier {
|
|
51
|
+
if (!Array.isArray(points) || points.length !== 4) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const [x1, y1, x2, y2] = points;
|
|
55
|
+
return (
|
|
56
|
+
isFiniteNumber(x1) &&
|
|
57
|
+
x1 >= 0 &&
|
|
58
|
+
x1 <= 1 &&
|
|
59
|
+
isFiniteNumber(y1) &&
|
|
60
|
+
isFiniteNumber(x2) &&
|
|
61
|
+
x2 >= 0 &&
|
|
62
|
+
x2 <= 1 &&
|
|
63
|
+
isFiniteNumber(y2)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
22
67
|
export function toInstantWidgetLayoutSizeUpdate(
|
|
23
68
|
size: WidgetLayoutSize,
|
|
24
69
|
): WidgetLayoutSizeUpdate {
|
|
@@ -27,3 +72,41 @@ export function toInstantWidgetLayoutSizeUpdate(
|
|
|
27
72
|
transition: INSTANT_WIDGET_LAYOUT_SIZE_TRANSITION,
|
|
28
73
|
};
|
|
29
74
|
}
|
|
75
|
+
|
|
76
|
+
export function toTimedWidgetLayoutSizeTransition(input: {
|
|
77
|
+
durationMs: number;
|
|
78
|
+
easing: WidgetLayoutCubicBezier;
|
|
79
|
+
}): WidgetLayoutTimedSizeTransition {
|
|
80
|
+
if (!Number.isFinite(input.durationMs) || input.durationMs <= 0) {
|
|
81
|
+
throw new RangeError(
|
|
82
|
+
"Timed widget layout transitions require durationMs > 0",
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
if (!isWidgetLayoutCubicBezier(input.easing)) {
|
|
86
|
+
throw new RangeError(
|
|
87
|
+
"Timed widget layout transitions require cubic-bezier x control points in [0, 1] and finite y control points",
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
kind: "timed",
|
|
92
|
+
durationMs: input.durationMs,
|
|
93
|
+
easing: {
|
|
94
|
+
kind: "cubic-bezier",
|
|
95
|
+
points: [...input.easing],
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function toTimedWidgetLayoutSizeUpdate(input: {
|
|
101
|
+
size: WidgetLayoutSize;
|
|
102
|
+
durationMs: number;
|
|
103
|
+
easing: WidgetLayoutCubicBezier;
|
|
104
|
+
}): WidgetLayoutTimedSizeUpdate {
|
|
105
|
+
return {
|
|
106
|
+
size: { ...input.size },
|
|
107
|
+
transition: toTimedWidgetLayoutSizeTransition({
|
|
108
|
+
durationMs: input.durationMs,
|
|
109
|
+
easing: input.easing,
|
|
110
|
+
}),
|
|
111
|
+
};
|
|
112
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -22,6 +22,14 @@ export {
|
|
|
22
22
|
appEventTrackSchema,
|
|
23
23
|
reservedSystemAppEventNames,
|
|
24
24
|
} from "./app-event.js";
|
|
25
|
+
export {
|
|
26
|
+
type AttentionPolicyConfig,
|
|
27
|
+
attentionBlockedBroadcastStrategySchema,
|
|
28
|
+
attentionExclusiveSurfaceStrategySchema,
|
|
29
|
+
attentionPolicyConfigSchema,
|
|
30
|
+
attentionPolicySourceSchema,
|
|
31
|
+
DEFAULT_ATTENTION_POLICY_CONFIG,
|
|
32
|
+
} from "./attention-policy.js";
|
|
25
33
|
export {
|
|
26
34
|
type ClientMeta,
|
|
27
35
|
clientMetaSchema,
|
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
appEventPayloadSchema,
|
|
12
12
|
appEventSurveyViewedSchema,
|
|
13
13
|
appEventTrackSchema,
|
|
14
|
+
attentionPolicyConfigSchema,
|
|
15
|
+
DEFAULT_ATTENTION_POLICY_CONFIG,
|
|
14
16
|
DEFAULT_AUTO_DETECT_COLOR_SCHEME_ATTRS,
|
|
15
17
|
flowVersionResolutionSchema,
|
|
16
18
|
getScopeMeta,
|
|
@@ -54,6 +56,18 @@ describe("@getuserfeedback/protocol root contract", () => {
|
|
|
54
56
|
]);
|
|
55
57
|
});
|
|
56
58
|
|
|
59
|
+
it("exports attention policy config defaults and schema", () => {
|
|
60
|
+
expect(
|
|
61
|
+
attentionPolicyConfigSchema.parse(DEFAULT_ATTENTION_POLICY_CONFIG),
|
|
62
|
+
).toEqual({
|
|
63
|
+
version: "attention-policy-default-v1",
|
|
64
|
+
source: "default",
|
|
65
|
+
recentFlowCooldownMs: 5 * 60 * 1000,
|
|
66
|
+
exclusiveSurfaceStrategy: "queue",
|
|
67
|
+
blockedBroadcastStrategy: "queue",
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
57
71
|
it("parses widget-config flag and capability inputs via canonical app-event schemas", () => {
|
|
58
72
|
expect(
|
|
59
73
|
appEventFlagSchema.parse({
|