@peekling/runtime 0.1.0 → 0.1.2
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/README.md +59 -8
- package/dist/canvas-renderer.d.ts +17 -0
- package/dist/canvas-renderer.d.ts.map +1 -0
- package/dist/canvas-renderer.js +192 -0
- package/dist/canvas.d.ts +5 -0
- package/dist/canvas.d.ts.map +1 -0
- package/dist/canvas.js +6 -0
- package/dist/configuration-validation.d.ts.map +1 -1
- package/dist/configuration-validation.js +176 -1
- package/dist/content.d.ts +3 -0
- package/dist/content.d.ts.map +1 -1
- package/dist/content.js +33 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/input.d.ts.map +1 -1
- package/dist/input.js +4 -1
- package/dist/interaction.d.ts +37 -0
- package/dist/interaction.d.ts.map +1 -0
- package/dist/interaction.js +204 -0
- package/dist/overrides.d.ts +8 -0
- package/dist/overrides.d.ts.map +1 -1
- package/dist/overrides.js +18 -16
- package/dist/path-sampler.d.ts +9 -0
- package/dist/path-sampler.d.ts.map +1 -0
- package/dist/path-sampler.js +47 -0
- package/dist/peekling.css +1 -1
- package/dist/peekling.css.sri +1 -1
- package/dist/peekling.js +1365 -86
- package/dist/peekling.js.sri +1 -1
- package/dist/peekling.min.js +1 -1
- package/dist/peekling.min.js.sri +1 -1
- package/dist/plan-compiler.d.ts +2 -0
- package/dist/plan-compiler.d.ts.map +1 -1
- package/dist/plan-compiler.js +71 -14
- package/dist/plan.d.ts +27 -1
- package/dist/plan.d.ts.map +1 -1
- package/dist/plan.js +281 -22
- package/dist/registry.js +2 -2
- package/dist/renderer.d.ts +18 -1
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +1 -0
- package/dist/runtime-validation.d.ts.map +1 -1
- package/dist/runtime-validation.js +35 -0
- package/dist/runtime.d.ts +49 -3
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +365 -14
- package/dist/targets.d.ts +11 -0
- package/dist/targets.d.ts.map +1 -0
- package/dist/targets.js +106 -0
- package/dist/types.d.ts +61 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -1
package/dist/peekling.min.js.sri
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
sha384-
|
|
1
|
+
sha384-1p+Dobs8owBmemeSfa0ciVA+xFHqPe9FXpAO4pbheJPfZowG117I/+kFlsDa4jUq
|
package/dist/plan-compiler.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ export interface PlanCompileContext {
|
|
|
3
3
|
states?: ReadonlySet<string>;
|
|
4
4
|
capabilities?: ReadonlySet<PlanCapability>;
|
|
5
5
|
contentIds?: ReadonlySet<string>;
|
|
6
|
+
targets?: ReadonlySet<string>;
|
|
6
7
|
validateSelector?: (selector: string) => boolean;
|
|
8
|
+
validatePath?: (path: string) => boolean;
|
|
7
9
|
}
|
|
8
10
|
export interface CompiledPlanStateSelection {
|
|
9
11
|
readonly kind: "state" | "capability";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan-compiler.d.ts","sourceRoot":"","sources":["../src/plan-compiler.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,IAAI,EACT,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EAIrB,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAC;AAepB,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,YAAY,CAAC,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;IAC3C,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"plan-compiler.d.ts","sourceRoot":"","sources":["../src/plan-compiler.ts"],"names":[],"mappings":"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"}
|
package/dist/plan-compiler.js
CHANGED
|
@@ -316,7 +316,7 @@ function compileEffect(input, path, context, allowPayload) {
|
|
|
316
316
|
: compileState(input.state, `${path}.state`, context);
|
|
317
317
|
const motion = input.motion === undefined
|
|
318
318
|
? undefined
|
|
319
|
-
: compileMotion(input.motion, `${path}.motion
|
|
319
|
+
: compileMotion(input.motion, `${path}.motion`, context);
|
|
320
320
|
const surfaces = input.surfaces === undefined ? [] : input.surfaces;
|
|
321
321
|
if (!Array.isArray(surfaces) || surfaces.length > SURFACE_LIMIT) {
|
|
322
322
|
fail("surface-limit", `${path}.surfaces`, `must contain at most ${SURFACE_LIMIT} surfaces`);
|
|
@@ -421,21 +421,78 @@ function compileState(input, path, context) {
|
|
|
421
421
|
}
|
|
422
422
|
return freeze({ kind: "capability", name: input.capability });
|
|
423
423
|
}
|
|
424
|
-
function compileMotion(input, path) {
|
|
424
|
+
function compileMotion(input, path, context) {
|
|
425
425
|
object(input, path);
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
426
|
+
switch (input.type) {
|
|
427
|
+
case "follow-pointer":
|
|
428
|
+
closed(input, ["type", "speed", "arrivalRadius"], path);
|
|
429
|
+
bounded(input.speed, `${path}.speed`, 1, 1_000);
|
|
430
|
+
bounded(input.arrivalRadius, `${path}.arrivalRadius`, 0, 1_000);
|
|
431
|
+
break;
|
|
432
|
+
case "horizontal-patrol":
|
|
433
|
+
closed(input, ["type", "speed", "edgeInset"], path);
|
|
434
|
+
bounded(input.speed, `${path}.speed`, 1, 1_000);
|
|
435
|
+
bounded(input.edgeInset, `${path}.edgeInset`, 0, 1_000);
|
|
436
|
+
break;
|
|
437
|
+
case "viewport-traverse":
|
|
438
|
+
closed(input, ["type", "speed", "edgeInset", "clockwise"], path);
|
|
439
|
+
bounded(input.speed, `${path}.speed`, 1, 1_000);
|
|
440
|
+
bounded(input.edgeInset, `${path}.edgeInset`, 0, 1_000);
|
|
441
|
+
if (input.clockwise !== undefined &&
|
|
442
|
+
typeof input.clockwise !== "boolean") {
|
|
443
|
+
fail("invalid-motion", `${path}.clockwise`, "must be boolean");
|
|
444
|
+
}
|
|
445
|
+
break;
|
|
446
|
+
case "move-to":
|
|
447
|
+
closed(input, ["type", "x", "y", "speed", "arrivalRadius"], path);
|
|
448
|
+
bounded(input.x, `${path}.x`, -100_000, 100_000);
|
|
449
|
+
bounded(input.y, `${path}.y`, -100_000, 100_000);
|
|
450
|
+
bounded(input.speed, `${path}.speed`, 1, 1_000);
|
|
451
|
+
bounded(input.arrivalRadius, `${path}.arrivalRadius`, 0, 1_000);
|
|
452
|
+
break;
|
|
453
|
+
case "move-to-target":
|
|
454
|
+
closed(input, ["type", "target", "anchor", "speed", "arrivalRadius"], path);
|
|
455
|
+
id(input.target, `${path}.target`, "Target");
|
|
456
|
+
if (context.targets && !context.targets.has(input.target)) {
|
|
457
|
+
fail("unknown-target", `${path}.target`, `references unknown target ${input.target}`);
|
|
458
|
+
}
|
|
459
|
+
if (input.anchor !== undefined &&
|
|
460
|
+
!["center", "top", "right", "bottom", "left"].includes(input.anchor)) {
|
|
461
|
+
fail("invalid-motion", `${path}.anchor`, "is not supported");
|
|
462
|
+
}
|
|
463
|
+
bounded(input.speed, `${path}.speed`, 1, 1_000);
|
|
464
|
+
bounded(input.arrivalRadius, `${path}.arrivalRadius`, 0, 1_000);
|
|
465
|
+
break;
|
|
466
|
+
case "jump-to":
|
|
467
|
+
closed(input, ["type", "x", "y", "duration", "height"], path);
|
|
468
|
+
bounded(input.x, `${path}.x`, -100_000, 100_000);
|
|
469
|
+
bounded(input.y, `${path}.y`, -100_000, 100_000);
|
|
470
|
+
bounded(input.duration, `${path}.duration`, 100, 10_000);
|
|
471
|
+
bounded(input.height, `${path}.height`, 0, 2_000);
|
|
472
|
+
break;
|
|
473
|
+
case "svg-path": {
|
|
474
|
+
closed(input, ["type", "path", "duration", "loop", "relative"], path);
|
|
475
|
+
if (typeof input.path !== "string" ||
|
|
476
|
+
input.path.length < 1 ||
|
|
477
|
+
input.path.length > 4_096 ||
|
|
478
|
+
/[\0\r\n]/.test(input.path)) {
|
|
479
|
+
fail("invalid-path", `${path}.path`, "must be bounded SVG path data");
|
|
480
|
+
}
|
|
481
|
+
if (context.validatePath && !context.validatePath(input.path)) {
|
|
482
|
+
fail("invalid-path", `${path}.path`, "must be valid SVG path data");
|
|
483
|
+
}
|
|
484
|
+
bounded(input.duration, `${path}.duration`, 100, 60_000);
|
|
485
|
+
for (const field of ["loop", "relative"]) {
|
|
486
|
+
if (input[field] !== undefined && typeof input[field] !== "boolean") {
|
|
487
|
+
fail("invalid-motion", `${path}.${field}`, "must be boolean");
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
break;
|
|
491
|
+
}
|
|
492
|
+
default:
|
|
493
|
+
fail("invalid-motion", `${path}.type`, "is not a supported motion type");
|
|
429
494
|
}
|
|
430
|
-
|
|
431
|
-
bounded(input.arrivalRadius, `${path}.arrivalRadius`, 0, 1_000);
|
|
432
|
-
return freeze({
|
|
433
|
-
type: "follow-pointer",
|
|
434
|
-
...(input.speed === undefined ? {} : { speed: input.speed }),
|
|
435
|
-
...(input.arrivalRadius === undefined
|
|
436
|
-
? {}
|
|
437
|
-
: { arrivalRadius: input.arrivalRadius }),
|
|
438
|
-
});
|
|
495
|
+
return freeze({ ...input });
|
|
439
496
|
}
|
|
440
497
|
function compileSurface(input, path, context, allowPayload) {
|
|
441
498
|
object(input, path);
|
package/dist/plan.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { type CompiledPlan, type PlanEventEvaluation } from "./plan-compiler.js";
|
|
2
|
-
import { type BehaviorRequest, type Plan, type World } from "./types.js";
|
|
2
|
+
import { type BehaviorRequest, type HorizontalPatrolMotionEffect, type MotionRequest, type Plan, type PeeklingPreset, type ViewportTraverseMotionEffect, type World } from "./types.js";
|
|
3
3
|
export declare function compiledPlanSectionRequirements(plan: CompiledPlan): {
|
|
4
4
|
selectors: readonly string[];
|
|
5
5
|
thresholds: readonly number[];
|
|
6
6
|
};
|
|
7
7
|
/** The engine-owned default Plan policy. It uses the public Plan shape. */
|
|
8
8
|
export declare function createDefaultPlan(locomotion: boolean): Plan;
|
|
9
|
+
/** Small named starting points that compile into the canonical Plan. */
|
|
10
|
+
export declare function createPresetPlan(preset: PeeklingPreset, locomotion: boolean): Plan;
|
|
9
11
|
/** Instance-owned evaluator for one immutable compiled Plan. */
|
|
10
12
|
export declare class PlanRuntime {
|
|
11
13
|
#private;
|
|
@@ -18,4 +20,28 @@ export declare class PlanRuntime {
|
|
|
18
20
|
nextWakeAt(): number | undefined;
|
|
19
21
|
rebase(delta: number): void;
|
|
20
22
|
}
|
|
23
|
+
export type PatrolDirection = boolean;
|
|
24
|
+
interface PatrolWorld {
|
|
25
|
+
readonly position: Readonly<{
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
}>;
|
|
29
|
+
readonly viewport: Readonly<{
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
}>;
|
|
33
|
+
readonly characterSize: Readonly<{
|
|
34
|
+
width: number;
|
|
35
|
+
height: number;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
export declare function evaluateHorizontalPatrol(effect: Readonly<HorizontalPatrolMotionEffect>, world: Readonly<PatrolWorld>, direction: PatrolDirection): readonly [PatrolDirection, MotionRequest | undefined];
|
|
39
|
+
export declare function evaluateViewportTraverse(effect: Readonly<ViewportTraverseMotionEffect>, world: Readonly<PatrolWorld>, phase?: number): readonly [number, MotionRequest | undefined];
|
|
40
|
+
export declare function motionToward(effect: Readonly<{
|
|
41
|
+
speed?: number;
|
|
42
|
+
}>, position: Readonly<{
|
|
43
|
+
x: number;
|
|
44
|
+
y: number;
|
|
45
|
+
}>, x: number, y: number, arrivalRadius?: number, bounds?: Readonly<Partial<Pick<World, "viewport" | "characterSize">>>): MotionRequest | undefined;
|
|
46
|
+
export {};
|
|
21
47
|
//# sourceMappingURL=plan.d.ts.map
|
package/dist/plan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,YAAY,EAGjB,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,IAAI,EAGT,KAAK,KAAK,EACX,MAAM,YAAY,CAAC;AAEpB,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,YAAY,GAAG;IACnE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAgBA;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,YAAY,EAGjB,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,4BAA4B,EAEjC,KAAK,aAAa,EAClB,KAAK,IAAI,EAGT,KAAK,cAAc,EAInB,KAAK,4BAA4B,EACjC,KAAK,KAAK,EACX,MAAM,YAAY,CAAC;AAEpB,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,YAAY,GAAG;IACnE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAgBA;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI,CAE3D;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,OAAO,GAClB,IAAI,CA6CN;AAaD,gEAAgE;AAChE,qBAAa,WAAW;;IAmBtB,YAAY,IAAI,EAAE,YAAY,EAE7B;IAED,IAAI,IAAI,IAAI,YAAY,CAEvB;IAED,IAAI,eAAe,IAAI,mBAAmB,CAAC,QAAQ,CAAC,GAAG,SAAS,CAE/D;IAED,IAAI,mBAAmB,IAAI,mBAAmB,CAAC,kBAAkB,CAAC,CAEjE;IAED,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,eAAe,CAwMhD;IAED,KAAK,IAAI,IAAI,CAcZ;IAED,UAAU,IAAI,MAAM,GAAG,SAAS,CAU/B;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAM1B;CAgKF;AAgBD,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC;AAEtC,UAAU,WAAW;IACnB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrE;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,CAAC,4BAA4B,CAAC,EAC9C,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC5B,SAAS,EAAE,eAAe,GACzB,SAAS,CAAC,eAAe,EAAE,aAAa,GAAG,SAAS,CAAC,CAkBvD;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,CAAC,4BAA4B,CAAC,EAC9C,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC5B,KAAK,CAAC,EAAE,MAAM,GACb,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC,CAoC9C;AA6DD,wBAAgB,YAAY,CAC1B,MAAM,EAAE,QAAQ,CAAC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EACpC,QAAQ,EAAE,QAAQ,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC5C,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,aAAa,SAAI,EACjB,MAAM,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,GACpE,aAAa,GAAG,SAAS,CAwB3B"}
|
package/dist/plan.js
CHANGED
|
@@ -19,6 +19,32 @@ export function compiledPlanSectionRequirements(plan) {
|
|
|
19
19
|
}
|
|
20
20
|
/** The engine-owned default Plan policy. It uses the public Plan shape. */
|
|
21
21
|
export function createDefaultPlan(locomotion) {
|
|
22
|
+
return createPresetPlan("companion", locomotion);
|
|
23
|
+
}
|
|
24
|
+
/** Small named starting points that compile into the canonical Plan. */
|
|
25
|
+
export function createPresetPlan(preset, locomotion) {
|
|
26
|
+
const state = locomotion
|
|
27
|
+
? { capability: "locomotion" }
|
|
28
|
+
: { state: "idle" };
|
|
29
|
+
if (preset === "still") {
|
|
30
|
+
return {
|
|
31
|
+
baseline: {
|
|
32
|
+
channels: ["state"],
|
|
33
|
+
state: { state: "idle" },
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (preset === "bottom-patrol" || preset === "viewport-roam") {
|
|
38
|
+
return {
|
|
39
|
+
baseline: {
|
|
40
|
+
channels: ["motion", "state"],
|
|
41
|
+
state,
|
|
42
|
+
motion: preset === "bottom-patrol"
|
|
43
|
+
? { type: "horizontal-patrol", speed: DEFAULT_SPEED }
|
|
44
|
+
: { type: "viewport-traverse", speed: DEFAULT_SPEED },
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
22
48
|
return {
|
|
23
49
|
baseline: {
|
|
24
50
|
channels: ["state"],
|
|
@@ -47,6 +73,12 @@ export class PlanRuntime {
|
|
|
47
73
|
#eventState = createPlanEventState();
|
|
48
74
|
#activeChannels = new Map();
|
|
49
75
|
#activeSurfaces = new Map();
|
|
76
|
+
#patrolDirections = new WeakMap();
|
|
77
|
+
#traversePhases = new WeakMap();
|
|
78
|
+
#jumpOwner;
|
|
79
|
+
#jumpState;
|
|
80
|
+
#pathOwner;
|
|
81
|
+
#pathState;
|
|
50
82
|
#activeInterrupts = [];
|
|
51
83
|
#surfaceVersion = 0;
|
|
52
84
|
#lastEventStatus;
|
|
@@ -144,26 +176,78 @@ export class PlanRuntime {
|
|
|
144
176
|
if (state?.kind === "capability") {
|
|
145
177
|
output.capability = state.name;
|
|
146
178
|
}
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
179
|
+
const motionOwner = channels.get("motion");
|
|
180
|
+
const motion = motionOwner?.motion;
|
|
181
|
+
const settleCapability = () => {
|
|
182
|
+
if (output.capability !== "locomotion")
|
|
183
|
+
return;
|
|
184
|
+
delete output.capability;
|
|
185
|
+
const baseline = this.#baselineState();
|
|
186
|
+
if (!output.state && baseline)
|
|
187
|
+
output.state = baseline;
|
|
188
|
+
};
|
|
189
|
+
if (motion?.type !== "jump-to") {
|
|
190
|
+
this.#jumpOwner = undefined;
|
|
191
|
+
this.#jumpState = undefined;
|
|
192
|
+
}
|
|
193
|
+
if (motion?.type !== "svg-path") {
|
|
194
|
+
this.#pathOwner = undefined;
|
|
195
|
+
this.#pathState = undefined;
|
|
196
|
+
}
|
|
197
|
+
if (motion?.type === "horizontal-patrol" && world.characterSize) {
|
|
198
|
+
const [direction, request] = evaluateHorizontalPatrol(motion, world, this.#patrolDirections.get(motionOwner) ?? true);
|
|
199
|
+
this.#patrolDirections.set(motionOwner, direction);
|
|
200
|
+
if (request)
|
|
201
|
+
output.motion = request;
|
|
202
|
+
}
|
|
203
|
+
else if (motion?.type === "viewport-traverse" && world.characterSize) {
|
|
204
|
+
const [phase, request] = evaluateViewportTraverse(motion, world, this.#traversePhases.get(motionOwner));
|
|
205
|
+
this.#traversePhases.set(motionOwner, phase);
|
|
206
|
+
if (request)
|
|
207
|
+
output.motion = request;
|
|
208
|
+
}
|
|
209
|
+
else if (motion?.type === "follow-pointer") {
|
|
210
|
+
const request = world.pointer
|
|
211
|
+
? motionToward(motion, world.position, world.pointer.x, world.pointer.y, motion.arrivalRadius, world)
|
|
212
|
+
: undefined;
|
|
213
|
+
if (request)
|
|
214
|
+
output.motion = request;
|
|
215
|
+
else
|
|
216
|
+
settleCapability();
|
|
217
|
+
}
|
|
218
|
+
else if (motion?.type === "move-to") {
|
|
219
|
+
const request = motionToward(motion, world.position, motion.x, motion.y, motion.arrivalRadius, world);
|
|
220
|
+
if (request)
|
|
221
|
+
output.motion = request;
|
|
222
|
+
else
|
|
223
|
+
settleCapability();
|
|
224
|
+
}
|
|
225
|
+
else if (motion?.type === "move-to-target") {
|
|
226
|
+
const target = world.targets?.[motion.target];
|
|
227
|
+
const point = target && world.characterSize
|
|
228
|
+
? targetPoint(target, motion.anchor, world.characterSize)
|
|
229
|
+
: undefined;
|
|
230
|
+
const request = point
|
|
231
|
+
? motionToward(motion, world.position, point.x, point.y, motion.arrivalRadius, world)
|
|
232
|
+
: undefined;
|
|
233
|
+
if (request)
|
|
234
|
+
output.motion = { ...request, trackTarget: true };
|
|
235
|
+
else
|
|
236
|
+
settleCapability();
|
|
237
|
+
}
|
|
238
|
+
else if (motion?.type === "jump-to") {
|
|
239
|
+
const request = this.#evaluateJump(motionOwner, motion, world);
|
|
240
|
+
if (request)
|
|
241
|
+
output.motion = request;
|
|
242
|
+
else
|
|
243
|
+
settleCapability();
|
|
244
|
+
}
|
|
245
|
+
else if (motion?.type === "svg-path") {
|
|
246
|
+
const request = this.#evaluatePath(motionOwner, motion, world);
|
|
247
|
+
if (request)
|
|
248
|
+
output.motion = request;
|
|
249
|
+
else
|
|
250
|
+
settleCapability();
|
|
167
251
|
}
|
|
168
252
|
const selected = new Map();
|
|
169
253
|
for (const surface of this.#plan.baseline.surfaces) {
|
|
@@ -198,6 +282,12 @@ export class PlanRuntime {
|
|
|
198
282
|
this.#activeChannels.clear();
|
|
199
283
|
this.#activeSurfaces.clear();
|
|
200
284
|
this.#activeInterrupts = [];
|
|
285
|
+
this.#patrolDirections = new WeakMap();
|
|
286
|
+
this.#traversePhases = new WeakMap();
|
|
287
|
+
this.#jumpOwner = undefined;
|
|
288
|
+
this.#jumpState = undefined;
|
|
289
|
+
this.#pathOwner = undefined;
|
|
290
|
+
this.#pathState = undefined;
|
|
201
291
|
this.#eventState.ordering.clear();
|
|
202
292
|
this.#eventState.sessions.clear();
|
|
203
293
|
this.#lastEventStatus = undefined;
|
|
@@ -224,6 +314,67 @@ export class PlanRuntime {
|
|
|
224
314
|
const state = this.#plan.baseline.state;
|
|
225
315
|
return state?.kind === "state" ? state.name : undefined;
|
|
226
316
|
}
|
|
317
|
+
#evaluateJump(owner, effect, world) {
|
|
318
|
+
if (this.#jumpOwner !== owner || !this.#jumpState) {
|
|
319
|
+
this.#jumpOwner = owner;
|
|
320
|
+
this.#jumpState = {
|
|
321
|
+
startedAt: world.now,
|
|
322
|
+
from: { ...world.position },
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
const duration = effect.duration ?? 800;
|
|
326
|
+
const progress = Math.max(0, Math.min(1, (world.now - this.#jumpState.startedAt) / duration));
|
|
327
|
+
const target = boundedPoint(effect, world);
|
|
328
|
+
const desired = {
|
|
329
|
+
x: this.#jumpState.from.x + (target.x - this.#jumpState.from.x) * progress,
|
|
330
|
+
y: this.#jumpState.from.y + (target.y - this.#jumpState.from.y) * progress,
|
|
331
|
+
};
|
|
332
|
+
const lift = progress === 0 || progress === 1
|
|
333
|
+
? 0
|
|
334
|
+
: Math.sin(Math.PI * progress) *
|
|
335
|
+
(effect.height ?? world.characterSize?.height ?? 32);
|
|
336
|
+
const request = directMotion(world.position, desired, lift);
|
|
337
|
+
if (progress < 1 || request.maxDistance)
|
|
338
|
+
return request;
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
#evaluatePath(owner, effect, world) {
|
|
342
|
+
const sample = world.samplePath;
|
|
343
|
+
if (!sample)
|
|
344
|
+
return;
|
|
345
|
+
const first = sample(effect.path, 0);
|
|
346
|
+
if (!first)
|
|
347
|
+
return;
|
|
348
|
+
if (this.#pathOwner !== owner || !this.#pathState) {
|
|
349
|
+
this.#pathOwner = owner;
|
|
350
|
+
this.#pathState = {
|
|
351
|
+
startedAt: world.now,
|
|
352
|
+
offset: effect.relative === false
|
|
353
|
+
? { x: 0, y: 0 }
|
|
354
|
+
: {
|
|
355
|
+
x: world.position.x - first.x,
|
|
356
|
+
y: world.position.y - first.y,
|
|
357
|
+
},
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
const duration = effect.duration ?? 4_000;
|
|
361
|
+
const elapsed = Math.max(0, world.now - this.#pathState.startedAt);
|
|
362
|
+
const complete = effect.loop !== true && elapsed >= duration;
|
|
363
|
+
const progress = effect.loop
|
|
364
|
+
? (elapsed % duration) / duration
|
|
365
|
+
: Math.min(1, elapsed / duration);
|
|
366
|
+
const point = sample(effect.path, progress);
|
|
367
|
+
if (!point)
|
|
368
|
+
return;
|
|
369
|
+
const desired = {
|
|
370
|
+
x: point.x + this.#pathState.offset.x,
|
|
371
|
+
y: point.y + this.#pathState.offset.y,
|
|
372
|
+
};
|
|
373
|
+
const request = directMotion(world.position, boundedPoint(desired, world));
|
|
374
|
+
if (!complete || request.maxDistance)
|
|
375
|
+
return request;
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
227
378
|
#isContinuous(rule, world) {
|
|
228
379
|
const condition = rule.when;
|
|
229
380
|
if (condition.source !== "browser")
|
|
@@ -232,9 +383,9 @@ export class PlanRuntime {
|
|
|
232
383
|
if (!world.pointer)
|
|
233
384
|
return false;
|
|
234
385
|
const motion = rule.effect.motion;
|
|
235
|
-
if (!motion)
|
|
386
|
+
if (!motion || motion.type !== "follow-pointer")
|
|
236
387
|
return true;
|
|
237
|
-
return (
|
|
388
|
+
return Boolean(motionToward(motion, world.position, world.pointer.x, world.pointer.y, motion.arrivalRadius, world));
|
|
238
389
|
}
|
|
239
390
|
if (condition.event !== "section.visibility")
|
|
240
391
|
return false;
|
|
@@ -285,3 +436,111 @@ export class PlanRuntime {
|
|
|
285
436
|
function completionSource(name) {
|
|
286
437
|
return browserCompletionEvent(name) ? "browser" : "application";
|
|
287
438
|
}
|
|
439
|
+
export function evaluateHorizontalPatrol(effect, world, direction) {
|
|
440
|
+
const halfWidth = world.characterSize.width / 2;
|
|
441
|
+
const inset = effect.edgeInset ?? 0;
|
|
442
|
+
const left = Math.min(world.viewport.width / 2, halfWidth + inset);
|
|
443
|
+
const right = world.viewport.width - left;
|
|
444
|
+
const halfHeight = world.characterSize.height / 2;
|
|
445
|
+
const y = Math.max(halfHeight, world.viewport.height - halfHeight);
|
|
446
|
+
let request = motionToward(effect, world.position, direction ? right : left, y);
|
|
447
|
+
if (!request) {
|
|
448
|
+
direction = !direction;
|
|
449
|
+
request = motionToward(effect, world.position, direction ? right : left, y);
|
|
450
|
+
}
|
|
451
|
+
return [direction, request];
|
|
452
|
+
}
|
|
453
|
+
export function evaluateViewportTraverse(effect, world, phase) {
|
|
454
|
+
const inset = effect.edgeInset ?? 0;
|
|
455
|
+
const halfWidth = world.characterSize.width / 2;
|
|
456
|
+
const halfHeight = world.characterSize.height / 2;
|
|
457
|
+
const left = Math.min(world.viewport.width / 2, halfWidth + inset);
|
|
458
|
+
const right = Math.max(left, world.viewport.width - left);
|
|
459
|
+
const top = Math.min(world.viewport.height / 2, halfHeight + inset);
|
|
460
|
+
const bottom = Math.max(top, world.viewport.height - halfHeight - inset);
|
|
461
|
+
const points = [
|
|
462
|
+
{ x: left, y: bottom },
|
|
463
|
+
{ x: right, y: bottom },
|
|
464
|
+
{ x: right, y: top },
|
|
465
|
+
{ x: left, y: top },
|
|
466
|
+
];
|
|
467
|
+
if (phase === undefined) {
|
|
468
|
+
phase = points.reduce((nearest, point, index) => Math.hypot(point.x - world.position.x, point.y - world.position.y) <
|
|
469
|
+
Math.hypot(points[nearest].x - world.position.x, points[nearest].y - world.position.y)
|
|
470
|
+
? index
|
|
471
|
+
: nearest, 0);
|
|
472
|
+
}
|
|
473
|
+
let target = points[phase];
|
|
474
|
+
let request = motionToward(effect, world.position, target.x, target.y);
|
|
475
|
+
if (!request) {
|
|
476
|
+
const direction = effect.clockwise === false ? -1 : 1;
|
|
477
|
+
phase = (phase + direction + points.length) % points.length;
|
|
478
|
+
target = points[phase];
|
|
479
|
+
request = motionToward(effect, world.position, target.x, target.y);
|
|
480
|
+
}
|
|
481
|
+
return [phase, request];
|
|
482
|
+
}
|
|
483
|
+
function targetPoint(target, anchor = "center", character) {
|
|
484
|
+
const center = {
|
|
485
|
+
x: target.left + target.width / 2,
|
|
486
|
+
y: target.top + target.height / 2,
|
|
487
|
+
};
|
|
488
|
+
switch (anchor) {
|
|
489
|
+
case "top":
|
|
490
|
+
return { x: center.x, y: target.top - character.height / 2 };
|
|
491
|
+
case "right":
|
|
492
|
+
return { x: target.right + character.width / 2, y: center.y };
|
|
493
|
+
case "bottom":
|
|
494
|
+
return { x: center.x, y: target.bottom + character.height / 2 };
|
|
495
|
+
case "left":
|
|
496
|
+
return { x: target.left - character.width / 2, y: center.y };
|
|
497
|
+
default:
|
|
498
|
+
return center;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
function boundedPoint(point, world) {
|
|
502
|
+
const size = world.characterSize;
|
|
503
|
+
if (!size)
|
|
504
|
+
return { x: point.x, y: point.y };
|
|
505
|
+
return {
|
|
506
|
+
x: Math.max(size.width / 2, Math.min(world.viewport.width - size.width / 2, point.x)),
|
|
507
|
+
y: Math.max(size.height / 2, Math.min(world.viewport.height - size.height / 2, point.y)),
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
function directMotion(position, target, lift = 0) {
|
|
511
|
+
const dx = target.x - position.x;
|
|
512
|
+
const dy = target.y - position.y;
|
|
513
|
+
const distance = Math.hypot(dx, dy);
|
|
514
|
+
return {
|
|
515
|
+
x: distance ? dx / distance : 0,
|
|
516
|
+
y: distance ? dy / distance : 0,
|
|
517
|
+
speed: 0,
|
|
518
|
+
maxDistance: distance,
|
|
519
|
+
lift,
|
|
520
|
+
direct: true,
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
export function motionToward(effect, position, x, y, arrivalRadius = 0, bounds) {
|
|
524
|
+
const size = bounds?.characterSize;
|
|
525
|
+
const viewport = bounds?.viewport;
|
|
526
|
+
if (size && viewport) {
|
|
527
|
+
const pointerX = x;
|
|
528
|
+
const pointerY = y;
|
|
529
|
+
x = Math.max(size.width / 2, Math.min(viewport.width - size.width / 2, x));
|
|
530
|
+
y = Math.max(size.height / 2, Math.min(viewport.height - size.height / 2, y));
|
|
531
|
+
if (x !== pointerX || y !== pointerY)
|
|
532
|
+
arrivalRadius = 0;
|
|
533
|
+
}
|
|
534
|
+
const dx = x - position.x;
|
|
535
|
+
const dy = y - position.y;
|
|
536
|
+
const distance = Math.hypot(dx, dy);
|
|
537
|
+
const maxDistance = distance - arrivalRadius;
|
|
538
|
+
if (maxDistance <= 4)
|
|
539
|
+
return;
|
|
540
|
+
return {
|
|
541
|
+
x: dx / distance,
|
|
542
|
+
y: dy / distance,
|
|
543
|
+
speed: effect.speed ?? DEFAULT_SPEED,
|
|
544
|
+
maxDistance,
|
|
545
|
+
};
|
|
546
|
+
}
|
package/dist/registry.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { runtimeMessage } from "./runtime-diagnostics.js";
|
|
2
2
|
const PEEK_REFERENCE_URL = typeof __PEEK_PACK_URL__ === "string"
|
|
3
3
|
? __PEEK_PACK_URL__
|
|
4
|
-
: "https://cdn.jsdelivr.net/npm/@peekling/pack-peek@0.1.
|
|
4
|
+
: "https://cdn.jsdelivr.net/npm/@peekling/pack-peek@0.1.1/character.json";
|
|
5
5
|
const PEEK_REFERENCE_SHA256 = typeof __PEEK_PACK_SHA256__ === "string"
|
|
6
6
|
? __PEEK_PACK_SHA256__
|
|
7
|
-
: "
|
|
7
|
+
: "9a2e2a41e85f7c4b8d3487a3655db40872675bd9c0780e139a946eabdf71d75f";
|
|
8
8
|
const REGISTRY = {
|
|
9
9
|
peek: Object.freeze({
|
|
10
10
|
url: PEEK_REFERENCE_URL,
|
package/dist/renderer.d.ts
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
import type { NormalizedPack, Point, StateDefinition } from "./types.js";
|
|
2
2
|
import { type RuntimeStyleAsset } from "./styles.js";
|
|
3
|
+
export interface CharacterRenderer {
|
|
4
|
+
readonly ready: Promise<void>;
|
|
5
|
+
swapAtlas(pack: NormalizedPack, atlasUrl: string): void | Promise<void>;
|
|
6
|
+
setHidden(hidden: boolean): void;
|
|
7
|
+
nextFrameIn(now: number): number | undefined;
|
|
8
|
+
render(stateName: string, now: number, position: Point, devicePixelRatio?: number, lift?: number): void;
|
|
9
|
+
destroy(): void;
|
|
10
|
+
}
|
|
11
|
+
export interface CharacterRendererOptions {
|
|
12
|
+
document: Document;
|
|
13
|
+
pack: NormalizedPack;
|
|
14
|
+
atlasUrl: string;
|
|
15
|
+
scale: number;
|
|
16
|
+
styles: RuntimeStyleAsset;
|
|
17
|
+
}
|
|
18
|
+
export type CharacterRendererFactory = (options: Readonly<CharacterRendererOptions>) => CharacterRenderer;
|
|
3
19
|
export declare function frameAt(state: StateDefinition, elapsed: number): number;
|
|
4
20
|
export declare function snapToDevicePixel(value: number, devicePixelRatio?: number): number;
|
|
5
|
-
export declare class AtlasRenderer {
|
|
21
|
+
export declare class AtlasRenderer implements CharacterRenderer {
|
|
6
22
|
#private;
|
|
7
23
|
readonly host: HTMLElement;
|
|
8
24
|
readonly ready: Promise<void>;
|
|
@@ -13,4 +29,5 @@ export declare class AtlasRenderer {
|
|
|
13
29
|
render(stateName: string, now: number, position: Point, devicePixelRatio?: number, lift?: number): void;
|
|
14
30
|
destroy(): void;
|
|
15
31
|
}
|
|
32
|
+
export declare const createAtlasRenderer: CharacterRendererFactory;
|
|
16
33
|
//# sourceMappingURL=renderer.d.ts.map
|
package/dist/renderer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGzE,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAErB,wBAAgB,OAAO,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAkBvE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,SAAI,GAAG,MAAM,CAM7E;AAED,qBAAa,
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGzE,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC7C,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,KAAK,EACf,gBAAgB,CAAC,EAAE,MAAM,EACzB,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAAC;IACR,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,MAAM,wBAAwB,GAAG,CACrC,OAAO,EAAE,QAAQ,CAAC,wBAAwB,CAAC,KACxC,iBAAiB,CAAC;AAEvB,wBAAgB,OAAO,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAkBvE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,SAAI,GAAG,MAAM,CAM7E;AAED,qBAAa,aAAc,YAAW,iBAAiB;;IACrD,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAe9B,YACE,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,iBAAiB,EAoB1B;IAED,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAGtD;IAoBD,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAG/B;IAED,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAuB3C;IAED,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,KAAK,EACf,gBAAgB,SAAI,EACpB,IAAI,SAAI,GACP,IAAI,CAkDN;IAED,OAAO,IAAI,IAAI,CAKd;CAkBF;AAED,eAAO,MAAM,mBAAmB,EAAE,wBAO/B,CAAC"}
|
package/dist/renderer.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-validation.d.ts","sourceRoot":"","sources":["../src/runtime-validation.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,sBAAsB,EACtB,KAAK,yBAAyB,EAC9B,gBAAgB,GACjB,MAAM,+BAA+B,CAAC;AAEvC,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,MAAM,GACd,SAAS,CAAC,WAAW,EAAE,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"runtime-validation.d.ts","sourceRoot":"","sources":["../src/runtime-validation.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,sBAAsB,EACtB,KAAK,yBAAyB,EAC9B,gBAAgB,GACjB,MAAM,+BAA+B,CAAC;AAEvC,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,MAAM,GACd,SAAS,CAAC,WAAW,EAAE,iBAAiB,CAAC,CA2B3C"}
|
|
@@ -16,6 +16,7 @@ export function validateRuntimeConfiguration(options, baseUrl) {
|
|
|
16
16
|
try {
|
|
17
17
|
compilePlan(options.plan, {
|
|
18
18
|
contentIds: new Set(Object.keys(content)),
|
|
19
|
+
targets: new Set(Object.keys(options.targets ?? {})),
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
catch (cause) {
|
|
@@ -98,6 +99,40 @@ function configurationMessage(code, path, detail) {
|
|
|
98
99
|
return `${detail ?? field} must be a function`;
|
|
99
100
|
case "invalid-plan":
|
|
100
101
|
return detail ?? "Plan is invalid";
|
|
102
|
+
case "incompatible-behavior":
|
|
103
|
+
return "Choose preset or plan, not both";
|
|
104
|
+
case "invalid-preset":
|
|
105
|
+
return "preset must be companion, still, bottom-patrol, or viewport-roam";
|
|
106
|
+
case "invalid-targets":
|
|
107
|
+
return "targets must be an object of target IDs and CSS selectors";
|
|
108
|
+
case "target-limit":
|
|
109
|
+
return "targets supports at most 16 entries";
|
|
110
|
+
case "invalid-target":
|
|
111
|
+
return "target IDs must be bounded lowercase IDs";
|
|
112
|
+
case "invalid-target-selector":
|
|
113
|
+
return "target selectors must be bounded CSS selector text";
|
|
114
|
+
case "invalid-interaction":
|
|
115
|
+
return "interaction contains an unsupported value";
|
|
116
|
+
case "invalid-interaction-event":
|
|
117
|
+
return "interaction events must be bounded application Event names";
|
|
118
|
+
case "missing-interaction-event":
|
|
119
|
+
return "pressEvent is required when press is emit";
|
|
120
|
+
case "incompatible-interaction-event":
|
|
121
|
+
return "pressEvent can be used only with the emit press action";
|
|
122
|
+
case "invalid-interaction-state":
|
|
123
|
+
return "interaction states must be valid Pack State names";
|
|
124
|
+
case "invalid-interaction-range":
|
|
125
|
+
return "interaction physics value is outside its supported range";
|
|
126
|
+
case "invalid-interaction-label":
|
|
127
|
+
return "interaction label must be short plain text";
|
|
128
|
+
case "invalid-catch-target":
|
|
129
|
+
return "catchTarget must reference a configured target";
|
|
130
|
+
case "invalid-catch-anchor":
|
|
131
|
+
return "catchAnchor is not supported";
|
|
132
|
+
case "invalid-indicator":
|
|
133
|
+
return "indicator must include a label and valid dot or count settings";
|
|
134
|
+
case "incompatible-indicator":
|
|
135
|
+
return "indicator requires character interaction";
|
|
101
136
|
default:
|
|
102
137
|
return detail ?? code;
|
|
103
138
|
}
|