@getuserfeedback/protocol 3.0.11 → 3.0.12
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/host/widget-layout-transition-plan.d.ts +18 -4
- package/dist/host/widget-layout-transition-plan.d.ts.map +1 -1
- package/dist/host/widget-layout-transition-plan.js +32 -8
- package/package.json +2 -2
- package/src/host/widget-layout-transition-plan.test.ts +73 -0
- package/src/host/widget-layout-transition-plan.ts +80 -13
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { WidgetLayoutSize, WidgetLayoutSizeUpdate, WidgetLayoutTimedSizeUpdate } from "./widget-layout-size-update.js";
|
|
2
2
|
export type WidgetLayoutComparableSizeUpdate = WidgetLayoutSizeUpdate | WidgetLayoutTimedSizeUpdate;
|
|
3
|
-
export type WidgetLayoutUnchangedTransitionPlan = {
|
|
3
|
+
export type WidgetLayoutUnchangedTransitionPlan<Update extends WidgetLayoutComparableSizeUpdate = WidgetLayoutComparableSizeUpdate> = {
|
|
4
4
|
kind: "unchanged";
|
|
5
5
|
size: WidgetLayoutSize;
|
|
6
|
-
update:
|
|
6
|
+
update: Update;
|
|
7
7
|
observedAtMs: number;
|
|
8
8
|
};
|
|
9
9
|
export type WidgetLayoutInstantTransitionPlan = {
|
|
@@ -13,12 +13,26 @@ export type WidgetLayoutInstantTransitionPlan = {
|
|
|
13
13
|
startedAtMs: number;
|
|
14
14
|
settledAtMs: number;
|
|
15
15
|
};
|
|
16
|
-
export type
|
|
16
|
+
export type WidgetLayoutTimedTransitionPlan = {
|
|
17
|
+
kind: "timed";
|
|
18
|
+
size: WidgetLayoutSize;
|
|
19
|
+
update: WidgetLayoutTimedSizeUpdate;
|
|
20
|
+
startedAtMs: number;
|
|
21
|
+
settledAtMs: number;
|
|
22
|
+
};
|
|
23
|
+
export type WidgetLayoutInstantOnlyTransitionPlan = WidgetLayoutUnchangedTransitionPlan<WidgetLayoutSizeUpdate> | WidgetLayoutInstantTransitionPlan;
|
|
24
|
+
export type WidgetLayoutTransitionPlan = WidgetLayoutInstantOnlyTransitionPlan;
|
|
25
|
+
export type WidgetLayoutTimedCapableTransitionPlan = WidgetLayoutUnchangedTransitionPlan | WidgetLayoutInstantTransitionPlan | WidgetLayoutTimedTransitionPlan;
|
|
17
26
|
export declare function getWidgetLayoutPlanNowMs(): number;
|
|
18
27
|
export declare function areWidgetLayoutSizeUpdatesEqual(left: WidgetLayoutComparableSizeUpdate | undefined, right: WidgetLayoutComparableSizeUpdate): boolean;
|
|
19
28
|
export declare function planWidgetLayoutTransition(input: {
|
|
20
29
|
previous?: WidgetLayoutSizeUpdate;
|
|
21
30
|
next: WidgetLayoutSizeUpdate;
|
|
22
31
|
nowMs: number;
|
|
23
|
-
}):
|
|
32
|
+
}): WidgetLayoutInstantOnlyTransitionPlan;
|
|
33
|
+
export declare function planWidgetLayoutTransition(input: {
|
|
34
|
+
previous?: WidgetLayoutComparableSizeUpdate;
|
|
35
|
+
next: WidgetLayoutComparableSizeUpdate;
|
|
36
|
+
nowMs: number;
|
|
37
|
+
}): WidgetLayoutTimedCapableTransitionPlan;
|
|
24
38
|
//# sourceMappingURL=widget-layout-transition-plan.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widget-layout-transition-plan.d.ts","sourceRoot":"","sources":["../../src/host/widget-layout-transition-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAChB,sBAAsB,EACtB,2BAA2B,EAC3B,MAAM,gCAAgC,CAAC;AAExC,MAAM,MAAM,gCAAgC,GACzC,sBAAsB,GACtB,2BAA2B,CAAC;AAE/B,MAAM,MAAM,mCAAmC,GAAG;
|
|
1
|
+
{"version":3,"file":"widget-layout-transition-plan.d.ts","sourceRoot":"","sources":["../../src/host/widget-layout-transition-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAChB,sBAAsB,EACtB,2BAA2B,EAC3B,MAAM,gCAAgC,CAAC;AAExC,MAAM,MAAM,gCAAgC,GACzC,sBAAsB,GACtB,2BAA2B,CAAC;AAE/B,MAAM,MAAM,mCAAmC,CAC9C,MAAM,SACL,gCAAgC,GAAG,gCAAgC,IACjE;IACH,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG;IAC/C,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC7C,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,2BAA2B,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAC9C,mCAAmC,CAAC,sBAAsB,CAAC,GAC3D,iCAAiC,CAAC;AAErC,MAAM,MAAM,0BAA0B,GAAG,qCAAqC,CAAC;AAE/E,MAAM,MAAM,sCAAsC,GAC/C,mCAAmC,GACnC,iCAAiC,GACjC,+BAA+B,CAAC;AAEnC,wBAAgB,wBAAwB,IAAI,MAAM,CAQjD;AAED,wBAAgB,+BAA+B,CAC9C,IAAI,EAAE,gCAAgC,GAAG,SAAS,EAClD,KAAK,EAAE,gCAAgC,GACrC,OAAO,CAiCT;AAsCD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IACjD,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;CACd,GAAG,qCAAqC,CAAC;AAC1C,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IACjD,QAAQ,CAAC,EAAE,gCAAgC,CAAC;IAC5C,IAAI,EAAE,gCAAgC,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC;CACd,GAAG,sCAAsC,CAAC"}
|
|
@@ -32,6 +32,27 @@ export function areWidgetLayoutSizeUpdatesEqual(left, right) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
function cloneWidgetLayoutSizeUpdate(update) {
|
|
36
|
+
if (update.transition.kind === "timed") {
|
|
37
|
+
return {
|
|
38
|
+
size: { ...update.size },
|
|
39
|
+
transition: {
|
|
40
|
+
...update.transition,
|
|
41
|
+
easing: {
|
|
42
|
+
...update.transition.easing,
|
|
43
|
+
points: [...update.transition.easing.points],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
size: { ...update.size },
|
|
50
|
+
transition: { ...update.transition },
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function isWidgetLayoutTimedSizeUpdate(update) {
|
|
54
|
+
return update.transition.kind === "timed";
|
|
55
|
+
}
|
|
35
56
|
export function planWidgetLayoutTransition(input) {
|
|
36
57
|
if (!Number.isFinite(input.nowMs)) {
|
|
37
58
|
throw new RangeError("Widget layout transition plans require finite nowMs");
|
|
@@ -40,20 +61,23 @@ export function planWidgetLayoutTransition(input) {
|
|
|
40
61
|
return {
|
|
41
62
|
kind: "unchanged",
|
|
42
63
|
size: { ...input.next.size },
|
|
43
|
-
update:
|
|
44
|
-
size: { ...input.next.size },
|
|
45
|
-
transition: { ...input.next.transition },
|
|
46
|
-
},
|
|
64
|
+
update: cloneWidgetLayoutSizeUpdate(input.next),
|
|
47
65
|
observedAtMs: input.nowMs,
|
|
48
66
|
};
|
|
49
67
|
}
|
|
68
|
+
if (isWidgetLayoutTimedSizeUpdate(input.next)) {
|
|
69
|
+
return {
|
|
70
|
+
kind: "timed",
|
|
71
|
+
size: { ...input.next.size },
|
|
72
|
+
update: cloneWidgetLayoutSizeUpdate(input.next),
|
|
73
|
+
startedAtMs: input.nowMs,
|
|
74
|
+
settledAtMs: input.nowMs + input.next.transition.durationMs,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
50
77
|
return {
|
|
51
78
|
kind: "instant",
|
|
52
79
|
size: { ...input.next.size },
|
|
53
|
-
update:
|
|
54
|
-
size: { ...input.next.size },
|
|
55
|
-
transition: { ...input.next.transition },
|
|
56
|
-
},
|
|
80
|
+
update: cloneWidgetLayoutSizeUpdate(input.next),
|
|
57
81
|
startedAtMs: input.nowMs,
|
|
58
82
|
settledAtMs: input.nowMs,
|
|
59
83
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getuserfeedback/protocol",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.12",
|
|
4
4
|
"description": "getuserfeedback widget protocol — host surface and (later) wire protocol",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"getuserfeedback",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
},
|
|
134
134
|
"scripts": {
|
|
135
135
|
"lint": "ultracite check .",
|
|
136
|
-
"build": "bun ../../scripts/clean-build-output.ts dist tsconfig.tsbuildinfo && tsc -b tsconfig.json",
|
|
136
|
+
"build": "bun ../../scripts/clean-build-output.ts dist tsconfig.tsbuildinfo && tsc -b tsconfig.json && bun scripts/verify-dist-js.ts",
|
|
137
137
|
"types": "bun ../../scripts/clean-build-output.ts dist tsconfig.tsbuildinfo && tsc -b tsconfig.json --emitDeclarationOnly",
|
|
138
138
|
"typecheck": "tsc -b tsconfig.json",
|
|
139
139
|
"test": "bun test --dots",
|
|
@@ -7,9 +7,18 @@ import {
|
|
|
7
7
|
areWidgetLayoutSizeUpdatesEqual,
|
|
8
8
|
getWidgetLayoutPlanNowMs,
|
|
9
9
|
planWidgetLayoutTransition,
|
|
10
|
+
type WidgetLayoutInstantOnlyTransitionPlan,
|
|
11
|
+
type WidgetLayoutTransitionPlan,
|
|
10
12
|
} from "./widget-layout-transition-plan.js";
|
|
11
13
|
|
|
12
14
|
describe("widget layout transition plan", () => {
|
|
15
|
+
function expectInstantOnlyPlan(
|
|
16
|
+
_plan: WidgetLayoutInstantOnlyTransitionPlan,
|
|
17
|
+
): void {}
|
|
18
|
+
function expectLegacyTransitionPlan(
|
|
19
|
+
_plan: WidgetLayoutTransitionPlan,
|
|
20
|
+
): void {}
|
|
21
|
+
|
|
13
22
|
test("uses the browser monotonic clock for layout plan timestamps", () => {
|
|
14
23
|
const originalPerformanceDescriptor = Object.getOwnPropertyDescriptor(
|
|
15
24
|
globalThis,
|
|
@@ -72,6 +81,19 @@ describe("widget layout transition plan", () => {
|
|
|
72
81
|
test("plans the first instant layout update at the requested time", () => {
|
|
73
82
|
const next = toInstantWidgetLayoutSizeUpdate({ width: 320, height: 240 });
|
|
74
83
|
|
|
84
|
+
expectInstantOnlyPlan(
|
|
85
|
+
planWidgetLayoutTransition({
|
|
86
|
+
next,
|
|
87
|
+
nowMs: 1_000,
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
expectLegacyTransitionPlan(
|
|
91
|
+
planWidgetLayoutTransition({
|
|
92
|
+
next,
|
|
93
|
+
nowMs: 1_000,
|
|
94
|
+
}),
|
|
95
|
+
);
|
|
96
|
+
|
|
75
97
|
expect(
|
|
76
98
|
planWidgetLayoutTransition({
|
|
77
99
|
next,
|
|
@@ -153,6 +175,37 @@ describe("widget layout transition plan", () => {
|
|
|
153
175
|
});
|
|
154
176
|
});
|
|
155
177
|
|
|
178
|
+
test("plans explicit timed updates with settled time from duration", () => {
|
|
179
|
+
const next = toTimedWidgetLayoutSizeUpdate({
|
|
180
|
+
size: { width: 320, height: 360 },
|
|
181
|
+
durationMs: 180,
|
|
182
|
+
easing: [0.2, 0, 0, 1],
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
expect(
|
|
186
|
+
planWidgetLayoutTransition({
|
|
187
|
+
next,
|
|
188
|
+
nowMs: 1_500,
|
|
189
|
+
}),
|
|
190
|
+
).toEqual({
|
|
191
|
+
kind: "timed",
|
|
192
|
+
size: { width: 320, height: 360 },
|
|
193
|
+
update: {
|
|
194
|
+
size: { width: 320, height: 360 },
|
|
195
|
+
transition: {
|
|
196
|
+
kind: "timed",
|
|
197
|
+
durationMs: 180,
|
|
198
|
+
easing: {
|
|
199
|
+
kind: "cubic-bezier",
|
|
200
|
+
points: [0.2, 0, 0, 1],
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
startedAtMs: 1_500,
|
|
205
|
+
settledAtMs: 1_680,
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
156
209
|
test("does not leak mutable references from the next update", () => {
|
|
157
210
|
const next = {
|
|
158
211
|
size: { width: 320, height: 240 },
|
|
@@ -171,6 +224,26 @@ describe("widget layout transition plan", () => {
|
|
|
171
224
|
expect(plan.update.transition.durationMs).toBe(0);
|
|
172
225
|
});
|
|
173
226
|
|
|
227
|
+
test("does not leak mutable timed transition points from the next update", () => {
|
|
228
|
+
const next = toTimedWidgetLayoutSizeUpdate({
|
|
229
|
+
size: { width: 320, height: 240 },
|
|
230
|
+
durationMs: 180,
|
|
231
|
+
easing: [0.2, 0, 0, 1],
|
|
232
|
+
});
|
|
233
|
+
const plan = planWidgetLayoutTransition({
|
|
234
|
+
next,
|
|
235
|
+
nowMs: 1_000,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
(next.transition.easing.points as unknown as number[])[0] = 0.4;
|
|
239
|
+
|
|
240
|
+
expect(plan.update.transition.kind).toBe("timed");
|
|
241
|
+
if (plan.update.transition.kind !== "timed") {
|
|
242
|
+
throw new Error("expected timed transition");
|
|
243
|
+
}
|
|
244
|
+
expect(plan.update.transition.easing.points).toEqual([0.2, 0, 0, 1]);
|
|
245
|
+
});
|
|
246
|
+
|
|
174
247
|
test("rejects non-finite plan time", () => {
|
|
175
248
|
expect(() =>
|
|
176
249
|
planWidgetLayoutTransition({
|
|
@@ -8,10 +8,13 @@ export type WidgetLayoutComparableSizeUpdate =
|
|
|
8
8
|
| WidgetLayoutSizeUpdate
|
|
9
9
|
| WidgetLayoutTimedSizeUpdate;
|
|
10
10
|
|
|
11
|
-
export type WidgetLayoutUnchangedTransitionPlan
|
|
11
|
+
export type WidgetLayoutUnchangedTransitionPlan<
|
|
12
|
+
Update extends
|
|
13
|
+
WidgetLayoutComparableSizeUpdate = WidgetLayoutComparableSizeUpdate,
|
|
14
|
+
> = {
|
|
12
15
|
kind: "unchanged";
|
|
13
16
|
size: WidgetLayoutSize;
|
|
14
|
-
update:
|
|
17
|
+
update: Update;
|
|
15
18
|
observedAtMs: number;
|
|
16
19
|
};
|
|
17
20
|
|
|
@@ -23,10 +26,25 @@ export type WidgetLayoutInstantTransitionPlan = {
|
|
|
23
26
|
settledAtMs: number;
|
|
24
27
|
};
|
|
25
28
|
|
|
26
|
-
export type
|
|
27
|
-
|
|
29
|
+
export type WidgetLayoutTimedTransitionPlan = {
|
|
30
|
+
kind: "timed";
|
|
31
|
+
size: WidgetLayoutSize;
|
|
32
|
+
update: WidgetLayoutTimedSizeUpdate;
|
|
33
|
+
startedAtMs: number;
|
|
34
|
+
settledAtMs: number;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type WidgetLayoutInstantOnlyTransitionPlan =
|
|
38
|
+
| WidgetLayoutUnchangedTransitionPlan<WidgetLayoutSizeUpdate>
|
|
28
39
|
| WidgetLayoutInstantTransitionPlan;
|
|
29
40
|
|
|
41
|
+
export type WidgetLayoutTransitionPlan = WidgetLayoutInstantOnlyTransitionPlan;
|
|
42
|
+
|
|
43
|
+
export type WidgetLayoutTimedCapableTransitionPlan =
|
|
44
|
+
| WidgetLayoutUnchangedTransitionPlan
|
|
45
|
+
| WidgetLayoutInstantTransitionPlan
|
|
46
|
+
| WidgetLayoutTimedTransitionPlan;
|
|
47
|
+
|
|
30
48
|
export function getWidgetLayoutPlanNowMs(): number {
|
|
31
49
|
const performanceNow =
|
|
32
50
|
typeof globalThis.performance?.now === "function"
|
|
@@ -75,11 +93,57 @@ export function areWidgetLayoutSizeUpdatesEqual(
|
|
|
75
93
|
}
|
|
76
94
|
}
|
|
77
95
|
|
|
96
|
+
function cloneWidgetLayoutSizeUpdate(
|
|
97
|
+
update: WidgetLayoutSizeUpdate,
|
|
98
|
+
): WidgetLayoutSizeUpdate;
|
|
99
|
+
function cloneWidgetLayoutSizeUpdate(
|
|
100
|
+
update: WidgetLayoutTimedSizeUpdate,
|
|
101
|
+
): WidgetLayoutTimedSizeUpdate;
|
|
102
|
+
function cloneWidgetLayoutSizeUpdate(
|
|
103
|
+
update: WidgetLayoutComparableSizeUpdate,
|
|
104
|
+
): WidgetLayoutComparableSizeUpdate;
|
|
105
|
+
function cloneWidgetLayoutSizeUpdate(
|
|
106
|
+
update: WidgetLayoutComparableSizeUpdate,
|
|
107
|
+
): WidgetLayoutComparableSizeUpdate {
|
|
108
|
+
if (update.transition.kind === "timed") {
|
|
109
|
+
return {
|
|
110
|
+
size: { ...update.size },
|
|
111
|
+
transition: {
|
|
112
|
+
...update.transition,
|
|
113
|
+
easing: {
|
|
114
|
+
...update.transition.easing,
|
|
115
|
+
points: [...update.transition.easing.points],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
size: { ...update.size },
|
|
122
|
+
transition: { ...update.transition },
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function isWidgetLayoutTimedSizeUpdate(
|
|
127
|
+
update: WidgetLayoutComparableSizeUpdate,
|
|
128
|
+
): update is WidgetLayoutTimedSizeUpdate {
|
|
129
|
+
return update.transition.kind === "timed";
|
|
130
|
+
}
|
|
131
|
+
|
|
78
132
|
export function planWidgetLayoutTransition(input: {
|
|
79
133
|
previous?: WidgetLayoutSizeUpdate;
|
|
80
134
|
next: WidgetLayoutSizeUpdate;
|
|
81
135
|
nowMs: number;
|
|
82
|
-
}):
|
|
136
|
+
}): WidgetLayoutInstantOnlyTransitionPlan;
|
|
137
|
+
export function planWidgetLayoutTransition(input: {
|
|
138
|
+
previous?: WidgetLayoutComparableSizeUpdate;
|
|
139
|
+
next: WidgetLayoutComparableSizeUpdate;
|
|
140
|
+
nowMs: number;
|
|
141
|
+
}): WidgetLayoutTimedCapableTransitionPlan;
|
|
142
|
+
export function planWidgetLayoutTransition(input: {
|
|
143
|
+
previous?: WidgetLayoutComparableSizeUpdate;
|
|
144
|
+
next: WidgetLayoutComparableSizeUpdate;
|
|
145
|
+
nowMs: number;
|
|
146
|
+
}): WidgetLayoutTimedCapableTransitionPlan {
|
|
83
147
|
if (!Number.isFinite(input.nowMs)) {
|
|
84
148
|
throw new RangeError("Widget layout transition plans require finite nowMs");
|
|
85
149
|
}
|
|
@@ -87,20 +151,23 @@ export function planWidgetLayoutTransition(input: {
|
|
|
87
151
|
return {
|
|
88
152
|
kind: "unchanged",
|
|
89
153
|
size: { ...input.next.size },
|
|
90
|
-
update:
|
|
91
|
-
size: { ...input.next.size },
|
|
92
|
-
transition: { ...input.next.transition },
|
|
93
|
-
},
|
|
154
|
+
update: cloneWidgetLayoutSizeUpdate(input.next),
|
|
94
155
|
observedAtMs: input.nowMs,
|
|
95
156
|
};
|
|
96
157
|
}
|
|
158
|
+
if (isWidgetLayoutTimedSizeUpdate(input.next)) {
|
|
159
|
+
return {
|
|
160
|
+
kind: "timed",
|
|
161
|
+
size: { ...input.next.size },
|
|
162
|
+
update: cloneWidgetLayoutSizeUpdate(input.next),
|
|
163
|
+
startedAtMs: input.nowMs,
|
|
164
|
+
settledAtMs: input.nowMs + input.next.transition.durationMs,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
97
167
|
return {
|
|
98
168
|
kind: "instant",
|
|
99
169
|
size: { ...input.next.size },
|
|
100
|
-
update:
|
|
101
|
-
size: { ...input.next.size },
|
|
102
|
-
transition: { ...input.next.transition },
|
|
103
|
-
},
|
|
170
|
+
update: cloneWidgetLayoutSizeUpdate(input.next),
|
|
104
171
|
startedAtMs: input.nowMs,
|
|
105
172
|
settledAtMs: input.nowMs,
|
|
106
173
|
};
|