@phin-tech/dottie 0.7.0 → 0.8.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.
- package/PARITY.md +3 -0
- package/README.md +3 -2
- package/dist/compile.js +97 -10
- package/dist/dottie-compile.mjs +98 -11
- package/dist/dottie-player.js +879 -43
- package/dist/dottie-player.min.js +55 -53
- package/dist/dottie.js +879 -43
- package/dist/types/clicks.d.ts +1 -0
- package/dist/types/flows.d.ts +26 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/measure.d.ts +58 -0
- package/dist/types/model.d.ts +66 -0
- package/dist/types/player.d.ts +12 -1
- package/dist/types/state.d.ts +28 -8
- package/dist/types/timeline.d.ts +10 -2
- package/package.json +1 -1
package/dist/types/clicks.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type Click = ({
|
|
|
13
13
|
}) & {
|
|
14
14
|
set?: Record<string, boolean>;
|
|
15
15
|
toggle?: string[];
|
|
16
|
+
reset?: true;
|
|
16
17
|
};
|
|
17
18
|
/** The marker called `name`: an exact match, else one that differs only in case. */
|
|
18
19
|
export declare function sceneNamed(name: string, markers: Marker[]): number;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Page, RGBA } from "./model.ts";
|
|
2
|
+
export declare const DEFAULT_EVERY = 0.5, DEFAULT_SPEED = 160, DEFAULT_SIZE = 12;
|
|
3
|
+
export declare const DEFAULT_COLOR: RGBA;
|
|
4
|
+
export declare const clamp: (v: number | null, fallback: number, lo: number, hi: number) => number;
|
|
5
|
+
/** The id of a flow's packet `k`: the flow's id with its last twelve digits standing for `k` (Flow.packetID). */
|
|
6
|
+
export declare function packetID(flow: string, k: number): string;
|
|
7
|
+
/** Every shape traffic from `from` can reach in `frame`, with the cheapest way to each (DottieDocument.flowTree):
|
|
8
|
+
* by the connectors' cost (1 each unless set), ties to the shape reached first, earlier connectors first. */
|
|
9
|
+
export declare function flowTree(from: string, frame: Page, offline?: Set<string>): FlowTree | null;
|
|
10
|
+
export declare class FlowTree {
|
|
11
|
+
settled: Set<string>;
|
|
12
|
+
came: Map<string, {
|
|
13
|
+
from: string;
|
|
14
|
+
via: string;
|
|
15
|
+
back: boolean;
|
|
16
|
+
}>;
|
|
17
|
+
readonly from: string;
|
|
18
|
+
constructor(from: string);
|
|
19
|
+
/** The first of `to` that can be reached; with `spread`, when the first can't be, every other one that can. */
|
|
20
|
+
goals(to: string[], spread: boolean): string[];
|
|
21
|
+
/** The connectors to `goal`, as [connector, backwards] hops. */
|
|
22
|
+
hops(goal: string): [string, boolean][];
|
|
23
|
+
}
|
|
24
|
+
/** The connectors traffic takes from `from` to the first of `to` it reaches in `frame`, as [connector, backwards]
|
|
25
|
+
* hops; null when none can be reached. */
|
|
26
|
+
export declare function flowRoute(from: string, to: string[], frame: Page, offline?: Set<string>): [string, boolean][] | null;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -20,4 +20,4 @@ export interface RenderOptions {
|
|
|
20
20
|
/** One page of a drawing as an SVG document, as Dottie's own SVG export draws it. */
|
|
21
21
|
export declare function render(source: string | DottieFile | unknown, options?: RenderOptions): string;
|
|
22
22
|
/** The library's version. */
|
|
23
|
-
export declare const VERSION = "0.
|
|
23
|
+
export declare const VERSION = "0.8.0";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Element, Flow, Gauge, Page, RGBA } from "./model.ts";
|
|
2
|
+
import { type MetricTerm } from "./state.ts";
|
|
3
|
+
/** A connector's or shape's metrics in one frame (ElementMetrics). */
|
|
4
|
+
export interface ElementMetrics {
|
|
5
|
+
throughput: number;
|
|
6
|
+
load: number | null;
|
|
7
|
+
delay: number;
|
|
8
|
+
backlog: number;
|
|
9
|
+
inFlight: number;
|
|
10
|
+
depth: number;
|
|
11
|
+
}
|
|
12
|
+
/** A flow's metrics in one frame (FlowMetrics). */
|
|
13
|
+
export interface FlowMetrics {
|
|
14
|
+
volume: number;
|
|
15
|
+
placed: number;
|
|
16
|
+
backlog: number;
|
|
17
|
+
backup: number;
|
|
18
|
+
transit: number | null;
|
|
19
|
+
}
|
|
20
|
+
/** Every metric of one frame (FrameMetrics). */
|
|
21
|
+
export interface FrameMetrics {
|
|
22
|
+
elements: Map<string, ElementMetrics>;
|
|
23
|
+
flows: Map<string, FlowMetrics>;
|
|
24
|
+
carry: Record<string, number>;
|
|
25
|
+
}
|
|
26
|
+
export declare const emptyMetrics: () => FrameMetrics;
|
|
27
|
+
/** `metric` of the element or flow `id`, or null when it has none. */
|
|
28
|
+
export declare function metricValue(m: FrameMetrics, metric: string, id: string): number | null;
|
|
29
|
+
/** A shape's delay as traffic feels it: 0...3600 seconds. */
|
|
30
|
+
export declare function delayOf(e: Element): number;
|
|
31
|
+
/** The key of a flow's queue at a shape in `FrameMetrics.carry` and `carried` (DottieDocument.queueKey). */
|
|
32
|
+
export declare const queueKey: (shape: string, flow: string) => string;
|
|
33
|
+
/** The packets the page's flows draw in `frame` (the page posed at `t`), with these values (null: every flow runs),
|
|
34
|
+
* and the frame's metrics (DottieDocument.flowFrame). `since` is the seconds since the page's state last changed
|
|
35
|
+
* (null: `t`), and `carried` how much each flow's queue held at that moment: since then a queue grows by its
|
|
36
|
+
* backlog, or drains at the room its way on has left. */
|
|
37
|
+
export declare function flowFrame(flows: Flow[] | null, frame: Page, t: number, values: Record<string, boolean> | null, offline?: Set<string>, sinceChange?: number | null, carried?: Record<string, number>): {
|
|
38
|
+
packets: Element[];
|
|
39
|
+
metrics: FrameMetrics;
|
|
40
|
+
};
|
|
41
|
+
/** The frame's metric for a condition's comparison: its target an element's anchor, or an element's or flow's id. */
|
|
42
|
+
export declare function metricLookup(m: FrameMetrics, frame: Page): (t: MetricTerm, own: string | null) => number | null;
|
|
43
|
+
/** `elements` with the looks of overrides that compare metrics applied, and gauges drawn as plain elements; with
|
|
44
|
+
* no values ("all", the editor), both are left as they are (DottieDocument.finishing). */
|
|
45
|
+
export declare function finishing(elements: Element[], metrics: FrameMetrics, values: Record<string, boolean> | null, frame: Page, flows: Flow[], since?: number, carried?: Record<string, number>): {
|
|
46
|
+
elements: Element[];
|
|
47
|
+
readings: Record<string, number>;
|
|
48
|
+
};
|
|
49
|
+
/** The key of a gauge's reading in `FrameMetrics.carry` and `carried` (DottieDocument.gaugeKey). */
|
|
50
|
+
export declare const gaugeKey: (id: string) => string;
|
|
51
|
+
export declare const GAUGE_GREEN: RGBA, GAUGE_AMBER: RGBA, GAUGE_RED: RGBA;
|
|
52
|
+
export declare const GAUGE_BLUE: RGBA, GAUGE_TRACK: RGBA, GAUGE_GRAY: RGBA;
|
|
53
|
+
/** A metric's value as a gauge shows it: a percentage for load and backup, seconds for transit and delay. */
|
|
54
|
+
export declare function formatted(metric: string, v: number | null): string;
|
|
55
|
+
/** `v` to `places` decimals, halves away from zero, trailing zeros dropped (DottieDocument.number). */
|
|
56
|
+
export declare function formatNumber(v: number, places: number): string;
|
|
57
|
+
/** A gauge drawn: its frame as a `.path` carrying the label, then the bar or dial (DottieDocument.gauge). */
|
|
58
|
+
export declare function gauge(e: Element, g: Gauge, value: number | null, frame: Page, flows: Flow[]): Element[];
|
package/dist/types/model.d.ts
CHANGED
|
@@ -55,6 +55,8 @@ export interface ConnectorData {
|
|
|
55
55
|
waypoints: StrokePoint[] | null;
|
|
56
56
|
/** Hops where the line crosses a connector drawn beneath it. */
|
|
57
57
|
hops: boolean | null;
|
|
58
|
+
/** What a flow's traffic pays to take this connector (ADR 0002); null is 1. */
|
|
59
|
+
cost: number | null;
|
|
58
60
|
}
|
|
59
61
|
export interface PathSubpath {
|
|
60
62
|
closed: boolean;
|
|
@@ -75,8 +77,31 @@ export interface ClickAction {
|
|
|
75
77
|
url: string | null;
|
|
76
78
|
set: Record<string, boolean> | null;
|
|
77
79
|
toggle: string[] | null;
|
|
80
|
+
/** Puts every page variable back to its starting value first. */
|
|
81
|
+
reset?: boolean | null;
|
|
78
82
|
}
|
|
79
83
|
/** How a clickable element looks under the pointer or with keyboard focus; null keeps its own. */
|
|
84
|
+
/** A change to an element while `when` holds (StateOverride): a field left null keeps the element's own. */
|
|
85
|
+
export interface StateOverride {
|
|
86
|
+
when: string;
|
|
87
|
+
stroke: RGBA | null;
|
|
88
|
+
fill: RGBA | null;
|
|
89
|
+
textColor: RGBA | null;
|
|
90
|
+
/** Multiplies the element's opacity. */
|
|
91
|
+
opacity: number | null;
|
|
92
|
+
strokeWidth: number | null;
|
|
93
|
+
dash: DashStyle | null;
|
|
94
|
+
text: string | null;
|
|
95
|
+
/** Connector ids (uppercase) to the connectors a following element takes instead. */
|
|
96
|
+
reroute: Record<string, string> | null;
|
|
97
|
+
/** Still drawn, but carries no flow traffic. */
|
|
98
|
+
offline: boolean | null;
|
|
99
|
+
/** A connector's cost for flow traffic meanwhile. */
|
|
100
|
+
cost: number | null;
|
|
101
|
+
/** Its capacity and delay meanwhile (ADR 0003). */
|
|
102
|
+
capacity: number | null;
|
|
103
|
+
delay: number | null;
|
|
104
|
+
}
|
|
80
105
|
export interface HoverLook {
|
|
81
106
|
stroke: RGBA | null;
|
|
82
107
|
fill: RGBA | null;
|
|
@@ -110,6 +135,8 @@ export interface Element {
|
|
|
110
135
|
hover: HoverLook | null;
|
|
111
136
|
/** A condition on the page's variables: drawn only while it holds (Element.when; see state.ts). */
|
|
112
137
|
when: string | null;
|
|
138
|
+
/** Changes to the element while a condition holds, in order (Element.overrides; see state.ts). */
|
|
139
|
+
overrides: StateOverride[] | null;
|
|
113
140
|
/** For a `symbol` element: the page's symbol it shows, how it plays it, and from how far in. */
|
|
114
141
|
symbol: string | null;
|
|
115
142
|
playback: SymbolPlayback | null;
|
|
@@ -131,6 +158,23 @@ export interface Element {
|
|
|
131
158
|
height: number;
|
|
132
159
|
} | null;
|
|
133
160
|
extension?: ExtensionRef | null;
|
|
161
|
+
/** The most flow volume it carries, and a shape's delay in seconds (ADR 0003). */
|
|
162
|
+
capacity?: number | null;
|
|
163
|
+
delay?: number | null;
|
|
164
|
+
/** A shape that is a queue: backlog waits at the nearest one before whatever is full. */
|
|
165
|
+
queue?: boolean | null;
|
|
166
|
+
/** Shows a metric; drawn as plain paths and a label when the page is posed (metrics.ts). */
|
|
167
|
+
gauge?: Gauge | null;
|
|
168
|
+
}
|
|
169
|
+
/** A metric shown in an element's frame (Gauge, ADR 0003). */
|
|
170
|
+
export interface Gauge {
|
|
171
|
+
metric: string;
|
|
172
|
+
of: string;
|
|
173
|
+
max: number | null;
|
|
174
|
+
warn: number | null;
|
|
175
|
+
alarm: number | null;
|
|
176
|
+
style: "number" | "bar" | "dial" | null;
|
|
177
|
+
label: string | null;
|
|
134
178
|
}
|
|
135
179
|
export interface Layer {
|
|
136
180
|
id: string;
|
|
@@ -210,6 +254,28 @@ export interface Page {
|
|
|
210
254
|
symbols: Symbol[] | null;
|
|
211
255
|
/** The page's variables and their starting values (DottieDocument.variables). */
|
|
212
256
|
variables: Record<string, boolean> | null;
|
|
257
|
+
/** Traffic routed over the connectors drawn in each frame (DottieDocument.flows; see flows.ts). */
|
|
258
|
+
flows: Flow[] | null;
|
|
259
|
+
}
|
|
260
|
+
/** Traffic from one shape to the first of `to` it can reach (Flow, ADR 0002). Numbers left null take defaults. */
|
|
261
|
+
export interface Flow {
|
|
262
|
+
id: string;
|
|
263
|
+
from: string;
|
|
264
|
+
to: string[];
|
|
265
|
+
every: number | null;
|
|
266
|
+
speed: number | null;
|
|
267
|
+
color: RGBA | null;
|
|
268
|
+
size: number | null;
|
|
269
|
+
when: string | null;
|
|
270
|
+
/** When the first destination can't be reached, deal packets across every other one that can. */
|
|
271
|
+
spread: boolean | null;
|
|
272
|
+
/** How much it carries (ADR 0003); null is 1. */
|
|
273
|
+
volume: number | null;
|
|
274
|
+
/** Its volume while a condition holds, the last that holds winning. */
|
|
275
|
+
overrides?: {
|
|
276
|
+
when: string;
|
|
277
|
+
volume: number | null;
|
|
278
|
+
}[] | null;
|
|
213
279
|
}
|
|
214
280
|
/** A drawing defined once on a page and placed by `symbol` elements, with its own timeline (Symbol). */
|
|
215
281
|
export interface Symbol {
|
package/dist/types/player.d.ts
CHANGED
|
@@ -14,6 +14,14 @@ export declare class Playback {
|
|
|
14
14
|
readonly sceneLoops: boolean[];
|
|
15
15
|
/** The page's variables now: their starting values until clicks change them. */
|
|
16
16
|
state: Record<string, boolean>;
|
|
17
|
+
/** When the variables last changed (performance.now() milliseconds): backlog piles up from then (ADR 0003). */
|
|
18
|
+
stateSince: number;
|
|
19
|
+
/** A still (the `at` attribute): backlog is drawn for the page time, not the wall clock. */
|
|
20
|
+
still: boolean;
|
|
21
|
+
/** What each queue held when the variables last changed, which it drains from (FrameMetrics.carry). */
|
|
22
|
+
carried: Record<string, number>;
|
|
23
|
+
/** Seconds since the variables last changed, or null for a still. */
|
|
24
|
+
sinceChange(now?: number): number | null;
|
|
17
25
|
readonly background: RGBA;
|
|
18
26
|
readonly ink: RGBA;
|
|
19
27
|
/** What clicking each clickable element does, by element id. */
|
|
@@ -31,7 +39,10 @@ export declare class Playback {
|
|
|
31
39
|
private overTimes;
|
|
32
40
|
private downTimes;
|
|
33
41
|
private hitTimes;
|
|
34
|
-
|
|
42
|
+
last: {
|
|
43
|
+
t: number;
|
|
44
|
+
i: number;
|
|
45
|
+
};
|
|
35
46
|
private svg;
|
|
36
47
|
private groups;
|
|
37
48
|
private order;
|
package/dist/types/state.d.ts
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ClickAction, type Element, type Page, type StateOverride } from "./model.ts";
|
|
2
2
|
/** Whether `name` can name a variable: a letter or underscore, then letters, digits and underscores. */
|
|
3
3
|
export declare function isName(name: string): boolean;
|
|
4
|
-
/** The
|
|
5
|
-
|
|
4
|
+
/** The metrics a condition can compare (ADR 0003), as `load(workers) > 0.9`. */
|
|
5
|
+
export declare const METRIC_NAMES: string[];
|
|
6
|
+
/** A comparison of a metric in a condition (PageState.MetricTerm). */
|
|
7
|
+
export interface MetricTerm {
|
|
8
|
+
metric: string;
|
|
9
|
+
target: string;
|
|
10
|
+
op: string;
|
|
11
|
+
value: number;
|
|
12
|
+
}
|
|
13
|
+
/** `term` (trimmed) read as a metric comparison, or null. */
|
|
14
|
+
export declare function metricTerm(term: string): MetricTerm | null;
|
|
15
|
+
/** Whether `condition` compares a metric anywhere. */
|
|
16
|
+
export declare function mentionsMetric(condition: string): boolean;
|
|
17
|
+
/** The variable names `condition` reads, or null when it isn't one: names, each optionally after `!`, or metric
|
|
18
|
+
* comparisons, joined by `&&` and `||` (`&&` binds tighter). */
|
|
6
19
|
export declare function conditionNames(condition: string): string[] | null;
|
|
7
|
-
/** Whether `condition` holds with these values
|
|
8
|
-
* holds. */
|
|
9
|
-
export declare function holds(condition: string, state: Record<string, boolean
|
|
20
|
+
/** Whether `condition` holds with these values, and `metric` giving the frame's metrics. A missing variable is
|
|
21
|
+
* false, and so is a comparison whose metric can't be had; a condition that can't be read never holds. */
|
|
22
|
+
export declare function holds(condition: string, state: Record<string, boolean>, metric?: ((m: MetricTerm) => number | null) | null): boolean;
|
|
10
23
|
/** Which elements a page shows as far as its variables go: their starting values ("initial"), these values (a
|
|
11
24
|
* missing one takes its starting value), or every element ("all"). */
|
|
12
25
|
export type StateChoice = "initial" | "all" | Record<string, boolean>;
|
|
@@ -14,7 +27,14 @@ export type StateChoice = "initial" | "all" | Record<string, boolean>;
|
|
|
14
27
|
export declare function stateValues(page: Page, choice: StateChoice): Record<string, boolean> | null;
|
|
15
28
|
/** The ids of the elements whose `when` doesn't hold under `choice`. */
|
|
16
29
|
export declare function stateHidden(page: Page, choice: StateChoice): Set<string>;
|
|
30
|
+
/** The overrides of `e` that hold under `values`, in order; none for null ("all", the editor). */
|
|
31
|
+
export declare function activeOverrides(e: Element, values: Record<string, boolean> | null): StateOverride[];
|
|
32
|
+
/** Only what an override comparing metrics may change: its looks (ADR 0003). */
|
|
33
|
+
export declare function looksOnly(o: StateOverride): StateOverride;
|
|
34
|
+
/** `e` with `o` applied (StateOverride.apply): opacity multiplies, the rest replaces. */
|
|
35
|
+
export declare function applyOverride(o: StateOverride, e: Element): Element;
|
|
17
36
|
/** Whether a click sets or flips a variable. */
|
|
18
37
|
export declare function changesState(c: ClickAction | null): boolean;
|
|
19
|
-
/** `state` after the click:
|
|
20
|
-
|
|
38
|
+
/** `state` after the click: the starting values (`initial`) back if it resets, then its `set` values, then each
|
|
39
|
+
* `toggle` flipped (a missing variable starts false). */
|
|
40
|
+
export declare function applyClick(c: ClickAction, state: Record<string, boolean>, initial?: Record<string, boolean>): Record<string, boolean>;
|
package/dist/types/timeline.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Ease, type Element, type Follow, type Page, type Timeline, type Track } from "./model.ts";
|
|
2
2
|
import { Polyline, type Point, type Rect } from "./path.ts";
|
|
3
3
|
import { type StateChoice } from "./state.ts";
|
|
4
|
+
import { type FrameMetrics } from "./measure.ts";
|
|
4
5
|
export declare function applyEase(ease: Ease, u: number): number;
|
|
5
6
|
/** The time inside the track's own keys that `t` plays (repeats folded back). */
|
|
6
7
|
export declare function localTime(track: Track, t: number): number;
|
|
@@ -21,10 +22,17 @@ export declare function following(track: Track, e: Element, t: number, page: Pag
|
|
|
21
22
|
export declare function marchOffset(tl: Timeline, speed: number, period: number, t: number): number;
|
|
22
23
|
/** The page as a still drawing at `t` seconds, symbol instances expanded (DottieDocument.resolved(at:)). A page with
|
|
23
24
|
* no timeline and no instances is returned as is. */
|
|
24
|
-
export declare function resolved(page: Page, t: number, state?: StateChoice): Page;
|
|
25
|
+
export declare function resolved(page: Page, t: number, state?: StateChoice, since?: number | null, carried?: Record<string, number>): Page;
|
|
25
26
|
/** The page posed at `t` seconds, instances kept, and the elements whose `when` doesn't hold under `state` left out
|
|
26
27
|
* with their connectors (DottieDocument.posed(at:state:)). */
|
|
27
|
-
export declare function posed(page: Page, t: number, state?: StateChoice): Page;
|
|
28
|
+
export declare function posed(page: Page, t: number, state?: StateChoice, since?: number | null, carried?: Record<string, number>): Page;
|
|
29
|
+
/** `posed`, and the frame's metrics (ADR 0003). `since` is the seconds since the page's state last changed, which
|
|
30
|
+
* backlog has been piling up for: the player passes the time since the last click; null is `t`, as exports draw it.
|
|
31
|
+
* `carried` is what each queue held when the state last changed (`FrameMetrics.carry` then), which it drains from. */
|
|
32
|
+
export declare function posedWithMetrics(page: Page, t: number, state?: StateChoice, since?: number | null, carried?: Record<string, number>): {
|
|
33
|
+
frame: Page;
|
|
34
|
+
metrics: FrameMetrics;
|
|
35
|
+
};
|
|
28
36
|
/** The moment a still picture of the page shows: its poster, else the end. */
|
|
29
37
|
export declare function posterTime(page: Page): number;
|
|
30
38
|
/** The page as a still picture (its poster frame when animated). */
|