@aglyn/plugins-ai 1.0.0-beta.258 → 1.0.0-beta.260
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/package.json +17 -17
- package/src/lib/jobs/ai-job-page-language.d.ts +14 -0
- package/src/lib/jobs/ai-job-page-language.js +22 -2
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.js +18 -27
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-template-step.js +7 -1
- package/src/lib/jobs/ai-job-template-step.js.map +1 -1
- package/src/lib/layout-language/ai-layout-motion.d.ts +75 -0
- package/src/lib/layout-language/ai-layout-motion.js +172 -0
- package/src/lib/layout-language/ai-layout-motion.js.map +1 -0
- package/src/lib/operator-alerts.js +1 -1
- package/src/lib/operator-alerts.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.d.ts +29 -0
- package/src/lib/runtime/ai-doctrine-validators.js +69 -0
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.js +5 -3
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/server/assist-edit.d.ts +21 -0
- package/src/lib/server/assist-edit.js +99 -21
- package/src/lib/server/assist-edit.js.map +1 -1
|
@@ -18,6 +18,7 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
|
18
18
|
import { linealRelationshipPermits } from "@aglyn/aglyn/app-utils/lineal-order";
|
|
19
19
|
import { SCREEN_SEO_TEXT_FIELDS, SCREEN_SEO_TEXT_GUIDANCE } from "@aglyn/aglyn/app-utils/screen-seo-fields";
|
|
20
20
|
import { CANVAS_ROOT_ELEMENT_ID } from "@aglyn/aglyn/foundation/constants/canvas";
|
|
21
|
+
import { ANIMATION_EASINGS, ANIMATION_MAX_DELAY_MS, ANIMATION_MAX_DURATION_MS, ANIMATION_MAX_STAGGER_STEP_MS, ANIMATION_NONE, ANIMATION_PRESETS, ANIMATION_TRIGGERS, NODE_ANIMATION_DELAY_PROP, NODE_ANIMATION_DURATION_PROP, NODE_ANIMATION_EASE_PROP, NODE_ANIMATION_PROP, NODE_ANIMATION_REPEAT_PROP, NODE_ANIMATION_STAGGER_PROP, NODE_ANIMATION_STAGGER_STEP_PROP, NODE_ANIMATION_TRIGGER_PROP } from "@aglyn/aglyn/app-utils/element-animation";
|
|
21
22
|
import { NODE_MAX_INTERACTIONS, nodeInteractionSelector } from "@aglyn/aglyn/app-utils/node-interactions";
|
|
22
23
|
import { ACTION_MAX_STEPS, CLIENT_INTERACTION_STEP_LABELS, validateInteraction } from "@aglyn/aglyn/app-utils/site-interactions";
|
|
23
24
|
import { ASSIST_EDIT_ACTION_ID, ASSIST_EDIT_CONTEXT_MAX_NODES, ASSIST_EDIT_CONTEXT_MAX_PROPS, ASSIST_EDIT_INTERACTION_EVENTS, ASSIST_EDIT_INTERACTION_STEPS, ASSIST_EDIT_MAX_DROPPED_REASONS, ASSIST_EDIT_OP_KINDS, ASSIST_EDIT_OUTLINE_TEXT_CHARS, ASSIST_EDIT_SELECTED_TEXT_CHARS, ASSIST_EDIT_TOOL_NAME, summarizeAssistEditOps } from "../model/assist-edit.js";
|
|
@@ -220,6 +221,66 @@ const strictObject = (properties)=>({
|
|
|
220
221
|
strict: true
|
|
221
222
|
};
|
|
222
223
|
}
|
|
224
|
+
/* ------------------------------------------------------------------ *
|
|
225
|
+
* An element's entrance motion (AGL-3838)
|
|
226
|
+
* ------------------------------------------------------------------ */ /**
|
|
227
|
+
* The settings an element's Animation section writes, and the values each
|
|
228
|
+
* takes: the vocabulary's own lists, and a whole number of milliseconds up to
|
|
229
|
+
* its cap. `none` takes an animation off, as the section's None does.
|
|
230
|
+
*/ const MOTION_SETTINGS = {
|
|
231
|
+
[NODE_ANIMATION_PROP]: ANIMATION_PRESETS,
|
|
232
|
+
[NODE_ANIMATION_TRIGGER_PROP]: ANIMATION_TRIGGERS,
|
|
233
|
+
[NODE_ANIMATION_EASE_PROP]: ANIMATION_EASINGS,
|
|
234
|
+
[NODE_ANIMATION_DURATION_PROP]: ANIMATION_MAX_DURATION_MS,
|
|
235
|
+
[NODE_ANIMATION_DELAY_PROP]: ANIMATION_MAX_DELAY_MS,
|
|
236
|
+
[NODE_ANIMATION_STAGGER_STEP_PROP]: ANIMATION_MAX_STAGGER_STEP_MS,
|
|
237
|
+
[NODE_ANIMATION_STAGGER_PROP]: 'switch',
|
|
238
|
+
[NODE_ANIMATION_REPEAT_PROP]: 'switch'
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* The line of the edit protocol that offers motion: a pure function of the
|
|
242
|
+
* vocabulary, so it sits in the cached prefix with the rest of the block.
|
|
243
|
+
*/ export const ASSIST_EDIT_MOTION_LINE = `- Animation: updateProps also sets ${NODE_ANIMATION_PROP} (${ANIMATION_PRESETS.filter((preset)=>preset !== ANIMATION_NONE).join(', ')}; ${ANIMATION_NONE} removes it), ` + `${NODE_ANIMATION_TRIGGER_PROP} (${ANIMATION_TRIGGERS.join(', ')}), ${NODE_ANIMATION_EASE_PROP} (${ANIMATION_EASINGS.join(', ')}), ` + `${NODE_ANIMATION_DURATION_PROP} and ${NODE_ANIMATION_DELAY_PROP} (ms ≤${ANIMATION_MAX_DURATION_MS}), ` + `${NODE_ANIMATION_STAGGER_PROP} ("true": its children in turn), ${NODE_ANIMATION_STAGGER_STEP_PROP} (ms ≤${ANIMATION_MAX_STAGGER_STEP_MS}).`;
|
|
244
|
+
/**
|
|
245
|
+
* An `updateProps` patch split into its motion settings, held to the
|
|
246
|
+
* vocabulary, and everything else, which the palette validator judges.
|
|
247
|
+
*
|
|
248
|
+
* Every element takes the motion settings — the renderer reads them off any
|
|
249
|
+
* node — so they are in no palette entry and the palette validator would drop
|
|
250
|
+
* them all. They are held here instead, and a value outside the vocabulary or
|
|
251
|
+
* past a cap is REFUSED with its reason, never coerced: a proposal that says
|
|
252
|
+
* "slide in over ten seconds" and lands as three would be an edit the card
|
|
253
|
+
* misdescribes.
|
|
254
|
+
*/ export function assistEditMotionPatch(props) {
|
|
255
|
+
const motion = {};
|
|
256
|
+
const rest = {};
|
|
257
|
+
const refused = [];
|
|
258
|
+
for (const [name, raw] of Object.entries(props)){
|
|
259
|
+
const allowed = MOTION_SETTINGS[name];
|
|
260
|
+
if (allowed === undefined) {
|
|
261
|
+
rest[name] = raw;
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const text = String(raw != null ? raw : '').trim();
|
|
265
|
+
if (allowed === 'switch') {
|
|
266
|
+
if (text === 'true' || text === 'false') motion[name] = text === 'true';
|
|
267
|
+
else refused.push(`${name} is "true" or "false"`);
|
|
268
|
+
} else if (typeof allowed === 'number') {
|
|
269
|
+
const ms = /^\d{1,5}$/.test(text) ? Number(text) : NaN;
|
|
270
|
+
if (ms <= allowed) motion[name] = ms;
|
|
271
|
+
else refused.push(`${name} is a whole number of milliseconds up to ${allowed}`);
|
|
272
|
+
} else if (allowed.includes(text)) {
|
|
273
|
+
motion[name] = text;
|
|
274
|
+
} else {
|
|
275
|
+
refused.push(`${name} is one of ${allowed.join(', ')}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
motion,
|
|
280
|
+
rest,
|
|
281
|
+
refused
|
|
282
|
+
};
|
|
283
|
+
}
|
|
223
284
|
/* ------------------------------------------------------------------ *
|
|
224
285
|
* The cached block
|
|
225
286
|
* ------------------------------------------------------------------ */ const DOCUMENT_NOUNS = {
|
|
@@ -244,6 +305,7 @@ const strictObject = (properties)=>({
|
|
|
244
305
|
ASSIST_MUSIC_EDIT_LINE,
|
|
245
306
|
'Operations — every field is required; fill the ones an operation does not use with "", [] or -1:',
|
|
246
307
|
'- updateProps: nodeId and props — only the settings to change, as name/value strings ("true" or "false" for a switch). Every other setting on the element is kept.',
|
|
308
|
+
ASSIST_EDIT_MOTION_LINE,
|
|
247
309
|
`- updateSx: nodeId and sx as key/value/breakpoint. A color is a theme token — ${AI_SX_TOKENS.palette.join(', ')} — never a hex, rgb or color name. A unitless number is theme spacing units; a size carries its unit ("320px", "50%"). breakpoint is "" or one of ${AI_SX_TOKENS.breakpoints.join(', ')}.`,
|
|
248
310
|
'- insertSubtree: parentId, index (-1 appends) and nodes — the new elements, nodes[0] their root, each listing its children by the ids you gave them in this operation. Build only from the elements below, and keep it small.',
|
|
249
311
|
'- move: nodeId, parentId and index — the position the element takes among the parent’s children once moved (-1 appends).',
|
|
@@ -1096,38 +1158,54 @@ const DELAYED_STEPS = new Set([
|
|
|
1096
1158
|
return;
|
|
1097
1159
|
}
|
|
1098
1160
|
case 'updateProps':
|
|
1161
|
+
{
|
|
1162
|
+
// Motion settings are held to the animation vocabulary, the rest to the palette (AGL-3838).
|
|
1163
|
+
const { motion, rest, refused } = assistEditMotionPatch(pending.props);
|
|
1164
|
+
if (refused.length) {
|
|
1165
|
+
violations.push(`${label}: ${refused.join('; ')}`);
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
if (!Object.keys(rest).length) {
|
|
1169
|
+
ops.push(_extends({}, pending, {
|
|
1170
|
+
props: motion
|
|
1171
|
+
}));
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
const result = validateAiNodePatch(pending.componentId, {
|
|
1175
|
+
props: rest
|
|
1176
|
+
});
|
|
1177
|
+
if (result.ok === false) {
|
|
1178
|
+
violations.push(`${label}: ${result.error}`);
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
if (!Object.keys(result.props).length) {
|
|
1182
|
+
violations.push(`${label}: ${result.repairs.length ? result.repairs.slice(0, 2).join('; ') : 'none of the settings named are ones this element takes'}`);
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1185
|
+
ops.push(_extends({}, pending, {
|
|
1186
|
+
props: _extends({}, result.props, motion)
|
|
1187
|
+
}));
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1099
1190
|
case 'updateSx':
|
|
1100
1191
|
{
|
|
1101
|
-
const result = validateAiNodePatch(pending.componentId,
|
|
1102
|
-
props: pending.props
|
|
1103
|
-
} : {
|
|
1192
|
+
const result = validateAiNodePatch(pending.componentId, {
|
|
1104
1193
|
sx: pending.sx
|
|
1105
1194
|
});
|
|
1106
1195
|
if (result.ok === false) {
|
|
1107
1196
|
violations.push(`${label}: ${result.error}`);
|
|
1108
1197
|
return;
|
|
1109
1198
|
}
|
|
1110
|
-
// The first repairs say why a patch came out empty — a
|
|
1199
|
+
// The first repairs say why a patch came out empty — a style the
|
|
1111
1200
|
// element does not take reads differently from one that carried
|
|
1112
1201
|
// markup, and the reader of `dropped` needs to tell them apart.
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
violations.push(`${label}: ${why('none of the settings named are ones this element takes')}`);
|
|
1117
|
-
return;
|
|
1118
|
-
}
|
|
1119
|
-
ops.push(_extends({}, pending, {
|
|
1120
|
-
props: result.props
|
|
1121
|
-
}));
|
|
1122
|
-
} else {
|
|
1123
|
-
if (!result.sx) {
|
|
1124
|
-
violations.push(`${label}: ${why('none of the styles named are allowed')}`);
|
|
1125
|
-
return;
|
|
1126
|
-
}
|
|
1127
|
-
ops.push(_extends({}, pending, {
|
|
1128
|
-
sx: result.sx
|
|
1129
|
-
}));
|
|
1202
|
+
if (!result.sx) {
|
|
1203
|
+
violations.push(`${label}: ${result.repairs.length ? result.repairs.slice(0, 2).join('; ') : 'none of the styles named are allowed'}`);
|
|
1204
|
+
return;
|
|
1130
1205
|
}
|
|
1206
|
+
ops.push(_extends({}, pending, {
|
|
1207
|
+
sx: result.sx
|
|
1208
|
+
}));
|
|
1131
1209
|
return;
|
|
1132
1210
|
}
|
|
1133
1211
|
case 'move':
|