@docentjs/core 0.1.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/LICENSE +21 -0
- package/README.md +31 -0
- package/dist/index.cjs +696 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +582 -0
- package/dist/index.d.ts +582 -0
- package/dist/index.js +670 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
//#region src/schema/tour.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Tour schema — the JSON contract shared by the core engine, every renderer,
|
|
4
|
+
* the visual builder and the hosted service.
|
|
5
|
+
*
|
|
6
|
+
* Everything in this file must stay JSON-serialisable. Functions (hooks) live
|
|
7
|
+
* in `hooks.ts` and are attached at runtime, keyed by step id.
|
|
8
|
+
*/
|
|
9
|
+
/** Current schema version. Bump only on breaking changes to this file. */
|
|
10
|
+
export declare const SCHEMA_VERSION: 1;
|
|
11
|
+
type SchemaVersion = typeof SCHEMA_VERSION;
|
|
12
|
+
/**
|
|
13
|
+
* Where a step points.
|
|
14
|
+
*
|
|
15
|
+
* - A bare string is a CSS selector (web only). Convenient for hand-written tours.
|
|
16
|
+
* - A {@link TargetSpec} is the portable, self-healing form the builder produces.
|
|
17
|
+
*
|
|
18
|
+
* Prefer `{ name }` over raw selectors: on the web it resolves to
|
|
19
|
+
* `[data-docent="<name>"]`, on native to a `testID`, so one tour works everywhere.
|
|
20
|
+
*/
|
|
21
|
+
type Target = string | TargetSpec;
|
|
22
|
+
interface TargetSpec {
|
|
23
|
+
/**
|
|
24
|
+
* Logical name. Web: `[data-docent="<name>"]`. Native: `testID` / `nativeID`.
|
|
25
|
+
* The most robust anchor; survives refactors and works cross-platform.
|
|
26
|
+
*/
|
|
27
|
+
name?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Ordered CSS selector fallbacks (web only). Tried in order until one matches.
|
|
30
|
+
* The builder fills several so a tour keeps working after markup changes.
|
|
31
|
+
*/
|
|
32
|
+
selectors?: string[];
|
|
33
|
+
/** Explicit native identifier when it differs from `name`. */
|
|
34
|
+
native?: string;
|
|
35
|
+
/** Restrict the search to a container matched by this selector. */
|
|
36
|
+
within?: string;
|
|
37
|
+
/** When a selector matches several elements, pick this index (default 0). */
|
|
38
|
+
nth?: number;
|
|
39
|
+
}
|
|
40
|
+
type Side = 'top' | 'right' | 'bottom' | 'left';
|
|
41
|
+
type Alignment = 'start' | 'center' | 'end';
|
|
42
|
+
/**
|
|
43
|
+
* Preferred popover position relative to the target. `auto` lets the renderer
|
|
44
|
+
* pick the side with the most room. Any placement flips or shifts when it
|
|
45
|
+
* would overflow the viewport.
|
|
46
|
+
*/
|
|
47
|
+
type Placement = 'auto' | Side | `${Side}-${Exclude<Alignment, 'center'>}`;
|
|
48
|
+
interface SpotlightOptions {
|
|
49
|
+
/** Space between the target's edge and the cutout, in px. */
|
|
50
|
+
padding?: number;
|
|
51
|
+
/** Corner radius of the cutout, in px. */
|
|
52
|
+
radius?: number;
|
|
53
|
+
/** Animate the cutout moving between targets. */
|
|
54
|
+
animate?: boolean;
|
|
55
|
+
}
|
|
56
|
+
interface OverlayOptions {
|
|
57
|
+
/** Backdrop colour, any CSS colour. */
|
|
58
|
+
color?: string;
|
|
59
|
+
/** Backdrop opacity, 0–1. */
|
|
60
|
+
opacity?: number;
|
|
61
|
+
}
|
|
62
|
+
interface ScrollOptions {
|
|
63
|
+
/** Scroll the target into view before showing the step. */
|
|
64
|
+
enabled?: boolean;
|
|
65
|
+
behavior?: 'auto' | 'smooth';
|
|
66
|
+
block?: 'start' | 'center' | 'end' | 'nearest';
|
|
67
|
+
}
|
|
68
|
+
interface Media {
|
|
69
|
+
type: 'image' | 'video';
|
|
70
|
+
src: string;
|
|
71
|
+
alt?: string;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* How a step completes.
|
|
75
|
+
*
|
|
76
|
+
* - `'button'` (default): the user presses Next.
|
|
77
|
+
* - `click` / `input`: the user interacts with the target (or another element).
|
|
78
|
+
* - `event`: a named event is emitted through the runtime.
|
|
79
|
+
* - `element`: an element appears (e.g. a menu the user was asked to open).
|
|
80
|
+
* - `delay`: automatically after `ms`.
|
|
81
|
+
*/
|
|
82
|
+
type Advance = 'button' | {
|
|
83
|
+
on: 'click';
|
|
84
|
+
target?: Target;
|
|
85
|
+
} | {
|
|
86
|
+
on: 'input';
|
|
87
|
+
target?: Target;
|
|
88
|
+
match?: string;
|
|
89
|
+
} | {
|
|
90
|
+
on: 'event';
|
|
91
|
+
name: string;
|
|
92
|
+
} | {
|
|
93
|
+
on: 'element';
|
|
94
|
+
target: Target;
|
|
95
|
+
} | {
|
|
96
|
+
on: 'delay';
|
|
97
|
+
ms: number;
|
|
98
|
+
};
|
|
99
|
+
/** Whether the user can interact with the spotlighted target. */
|
|
100
|
+
type Interaction = 'block' | 'allow';
|
|
101
|
+
/** What to do when a step's target cannot be found. */
|
|
102
|
+
type OnMissing = 'skip' | 'wait' | 'abort';
|
|
103
|
+
interface StepButtons {
|
|
104
|
+
back?: boolean;
|
|
105
|
+
next?: boolean;
|
|
106
|
+
skip?: boolean;
|
|
107
|
+
close?: boolean;
|
|
108
|
+
}
|
|
109
|
+
type TraitValue = string | number | boolean | null | string[];
|
|
110
|
+
type TraitOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'nin' | 'contains' | 'exists' | 'missing';
|
|
111
|
+
/**
|
|
112
|
+
* Serialisable predicate evaluated by the core at runtime.
|
|
113
|
+
* `custom` predicates are registered by name on the runtime.
|
|
114
|
+
*/
|
|
115
|
+
type Condition = {
|
|
116
|
+
type: 'trait';
|
|
117
|
+
key: string;
|
|
118
|
+
op: TraitOperator;
|
|
119
|
+
value?: TraitValue;
|
|
120
|
+
} | {
|
|
121
|
+
type: 'route';
|
|
122
|
+
pattern: string;
|
|
123
|
+
} | {
|
|
124
|
+
type: 'element';
|
|
125
|
+
target: Target;
|
|
126
|
+
exists?: boolean;
|
|
127
|
+
} | {
|
|
128
|
+
type: 'tour';
|
|
129
|
+
id: string;
|
|
130
|
+
state: TourProgressState;
|
|
131
|
+
} | {
|
|
132
|
+
type: 'all';
|
|
133
|
+
conditions: Condition[];
|
|
134
|
+
} | {
|
|
135
|
+
type: 'any';
|
|
136
|
+
conditions: Condition[];
|
|
137
|
+
} | {
|
|
138
|
+
type: 'not';
|
|
139
|
+
condition: Condition;
|
|
140
|
+
} | {
|
|
141
|
+
type: 'custom';
|
|
142
|
+
name: string;
|
|
143
|
+
args?: Record<string, TraitValue>;
|
|
144
|
+
};
|
|
145
|
+
type TourProgressState = 'not-started' | 'in-progress' | 'completed' | 'skipped';
|
|
146
|
+
/** What starts a tour. `manual` means only through the runtime API. */
|
|
147
|
+
type Trigger = {
|
|
148
|
+
type: 'manual';
|
|
149
|
+
} | {
|
|
150
|
+
type: 'auto';
|
|
151
|
+
delay?: number;
|
|
152
|
+
} | {
|
|
153
|
+
type: 'route';
|
|
154
|
+
pattern: string;
|
|
155
|
+
delay?: number;
|
|
156
|
+
} | {
|
|
157
|
+
type: 'element';
|
|
158
|
+
target: Target;
|
|
159
|
+
delay?: number;
|
|
160
|
+
} | {
|
|
161
|
+
type: 'event';
|
|
162
|
+
name: string;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* How often an eligible user sees the tour.
|
|
166
|
+
* - `once`: show once per {@link Tour.version}, however it ended.
|
|
167
|
+
* - `until-completed`: keep offering it until the user finishes it.
|
|
168
|
+
* - `always`: every time the trigger fires.
|
|
169
|
+
*/
|
|
170
|
+
type Frequency = 'once' | 'until-completed' | 'always';
|
|
171
|
+
/**
|
|
172
|
+
* Visual tokens, serialisable so a builder or customizer can produce them.
|
|
173
|
+
* Each maps to a CSS custom property in the renderer (`--docent-*`).
|
|
174
|
+
* Values are CSS strings, e.g. `'#111'`, `'12px'`, `'0 4px 12px rgba(0,0,0,.2)'`.
|
|
175
|
+
*/
|
|
176
|
+
interface Theme {
|
|
177
|
+
background?: string;
|
|
178
|
+
foreground?: string;
|
|
179
|
+
muted?: string;
|
|
180
|
+
accent?: string;
|
|
181
|
+
accentForeground?: string;
|
|
182
|
+
radius?: string;
|
|
183
|
+
shadow?: string;
|
|
184
|
+
font?: string;
|
|
185
|
+
width?: string;
|
|
186
|
+
overlay?: string;
|
|
187
|
+
overlayOpacity?: string;
|
|
188
|
+
duration?: string;
|
|
189
|
+
zIndex?: string;
|
|
190
|
+
}
|
|
191
|
+
interface Labels {
|
|
192
|
+
next?: string;
|
|
193
|
+
back?: string;
|
|
194
|
+
skip?: string;
|
|
195
|
+
done?: string;
|
|
196
|
+
close?: string;
|
|
197
|
+
/** Supports `{current}` and `{total}` placeholders. */
|
|
198
|
+
progress?: string;
|
|
199
|
+
}
|
|
200
|
+
interface Step {
|
|
201
|
+
/** Unique within the tour. Used for persistence, hooks and analytics. */
|
|
202
|
+
id: string;
|
|
203
|
+
/** Omit for a centred modal step (welcome / finish screens). */
|
|
204
|
+
target?: Target;
|
|
205
|
+
title?: string;
|
|
206
|
+
body?: string;
|
|
207
|
+
/** How `body` is interpreted. Renderers never inject raw HTML. */
|
|
208
|
+
format?: 'text' | 'markdown';
|
|
209
|
+
media?: Media;
|
|
210
|
+
placement?: Placement;
|
|
211
|
+
/** Per-step override of the tour's spotlight options. */
|
|
212
|
+
spotlight?: SpotlightOptions;
|
|
213
|
+
advance?: Advance;
|
|
214
|
+
interaction?: Interaction;
|
|
215
|
+
/** Skip this step when the condition is false. */
|
|
216
|
+
condition?: Condition;
|
|
217
|
+
onMissing?: OnMissing;
|
|
218
|
+
/** How long to wait for the target when `onMissing` is `wait`, in ms. */
|
|
219
|
+
waitFor?: number;
|
|
220
|
+
/** URL pattern this step belongs to. Enables multi-page tours. */
|
|
221
|
+
route?: string;
|
|
222
|
+
buttons?: StepButtons;
|
|
223
|
+
scroll?: ScrollOptions;
|
|
224
|
+
/** Free-form extension bag for the builder or integrations. */
|
|
225
|
+
meta?: Record<string, unknown>;
|
|
226
|
+
}
|
|
227
|
+
interface TourOptions {
|
|
228
|
+
/** Persist progress so the tour survives navigation and reloads. */
|
|
229
|
+
persist?: boolean;
|
|
230
|
+
frequency?: Frequency;
|
|
231
|
+
showProgress?: boolean;
|
|
232
|
+
/** Allow closing with Escape or the close button. */
|
|
233
|
+
allowClose?: boolean;
|
|
234
|
+
closeOnOverlayClick?: boolean;
|
|
235
|
+
keyboard?: boolean;
|
|
236
|
+
spotlight?: SpotlightOptions;
|
|
237
|
+
overlay?: OverlayOptions;
|
|
238
|
+
scroll?: ScrollOptions;
|
|
239
|
+
labels?: Labels;
|
|
240
|
+
/** Visual tokens applied on top of the renderer's theme. */
|
|
241
|
+
theme?: Theme;
|
|
242
|
+
/** Name of a template registered on the renderer (slots, css, theme). */
|
|
243
|
+
template?: string;
|
|
244
|
+
}
|
|
245
|
+
interface Tour {
|
|
246
|
+
schemaVersion: SchemaVersion;
|
|
247
|
+
/** Stable identifier. Used for persistence, targeting and analytics. */
|
|
248
|
+
id: string;
|
|
249
|
+
/** Bump to re-show the tour to users who already saw an older version. */
|
|
250
|
+
version?: number;
|
|
251
|
+
/** Human-readable name, mainly for the builder and dashboards. */
|
|
252
|
+
name?: string;
|
|
253
|
+
description?: string;
|
|
254
|
+
steps: Step[];
|
|
255
|
+
trigger?: Trigger;
|
|
256
|
+
/** All must hold for the tour to be eligible. */
|
|
257
|
+
conditions?: Condition[];
|
|
258
|
+
options?: TourOptions;
|
|
259
|
+
/** Free-form extension bag for the builder or integrations. */
|
|
260
|
+
meta?: Record<string, unknown>;
|
|
261
|
+
}
|
|
262
|
+
//#endregion
|
|
263
|
+
//#region src/define.d.ts
|
|
264
|
+
/**
|
|
265
|
+
* Identity helper that gives hand-written tours full type inference and
|
|
266
|
+
* fills in the schema version. Returns the same object.
|
|
267
|
+
*/
|
|
268
|
+
export declare function defineTour(tour: Omit<Tour, 'schemaVersion'> & {
|
|
269
|
+
schemaVersion?: SchemaVersion;
|
|
270
|
+
}): Tour;
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region src/seams.d.ts
|
|
273
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
274
|
+
interface TourSource {
|
|
275
|
+
/** Return every tour this source knows about. */
|
|
276
|
+
load(): MaybePromise<Tour[]>;
|
|
277
|
+
/**
|
|
278
|
+
* Optional live updates. Return an unsubscribe function.
|
|
279
|
+
* Lets a hosted source push tour changes without a page reload.
|
|
280
|
+
*/
|
|
281
|
+
subscribe?(listener: (tours: Tour[]) => void): () => void;
|
|
282
|
+
}
|
|
283
|
+
interface Identity {
|
|
284
|
+
/** Stable user id. Omit for anonymous visitors. */
|
|
285
|
+
id?: string;
|
|
286
|
+
/** Attributes that `trait` conditions evaluate against. */
|
|
287
|
+
traits: Record<string, TraitValue>;
|
|
288
|
+
}
|
|
289
|
+
export declare const ANONYMOUS_IDENTITY: Identity;
|
|
290
|
+
/**
|
|
291
|
+
* Key/value storage for progress and seen-state. Shape matches `localStorage`
|
|
292
|
+
* but every method may be async so React Native's AsyncStorage fits too.
|
|
293
|
+
*/
|
|
294
|
+
interface StorageAdapter {
|
|
295
|
+
get(key: string): MaybePromise<string | null>;
|
|
296
|
+
set(key: string, value: string): MaybePromise<void>;
|
|
297
|
+
remove(key: string): MaybePromise<void>;
|
|
298
|
+
}
|
|
299
|
+
type DocentEventType = 'tour:started' | 'tour:completed' | 'tour:skipped' | 'tour:aborted' | 'step:shown' | 'step:completed' | 'step:skipped' | 'step:missing';
|
|
300
|
+
interface DocentEvent {
|
|
301
|
+
type: DocentEventType;
|
|
302
|
+
tourId: string;
|
|
303
|
+
tourVersion: number;
|
|
304
|
+
stepId?: string;
|
|
305
|
+
stepIndex?: number;
|
|
306
|
+
/** Unix epoch milliseconds. */
|
|
307
|
+
timestamp: number;
|
|
308
|
+
identity: Identity;
|
|
309
|
+
}
|
|
310
|
+
/** Receives every lifecycle event. Wire it to console, your analytics, or a hosted endpoint. */
|
|
311
|
+
interface EventSink {
|
|
312
|
+
emit(event: DocentEvent): void;
|
|
313
|
+
}
|
|
314
|
+
//#endregion
|
|
315
|
+
//#region src/engine/conditions.d.ts
|
|
316
|
+
type CustomPredicate = (args?: Record<string, TraitValue>) => boolean;
|
|
317
|
+
interface ConditionEnv {
|
|
318
|
+
identity: Identity;
|
|
319
|
+
/** Current path, e.g. `/invoices/new`. */
|
|
320
|
+
route?: string;
|
|
321
|
+
elementExists?: (target: Target) => boolean;
|
|
322
|
+
tourState?: (tourId: string) => TourProgressState;
|
|
323
|
+
custom?: Record<string, CustomPredicate>;
|
|
324
|
+
}
|
|
325
|
+
export declare function evaluateTrait(actual: TraitValue | undefined, op: Extract<Condition, {
|
|
326
|
+
type: 'trait';
|
|
327
|
+
}>['op'], expected: TraitValue | undefined): boolean;
|
|
328
|
+
export declare function evaluateCondition(condition: Condition, env: ConditionEnv): boolean;
|
|
329
|
+
/** All conditions must hold. An empty or missing list holds. */
|
|
330
|
+
export declare function evaluateAll(conditions: Condition[] | undefined, env: ConditionEnv): boolean;
|
|
331
|
+
//#endregion
|
|
332
|
+
//#region src/hooks.d.ts
|
|
333
|
+
interface StepContext {
|
|
334
|
+
tour: Tour;
|
|
335
|
+
step: Step;
|
|
336
|
+
index: number;
|
|
337
|
+
total: number;
|
|
338
|
+
}
|
|
339
|
+
interface StepHooks {
|
|
340
|
+
/**
|
|
341
|
+
* Runs before the step renders. Open a menu, navigate, fetch data.
|
|
342
|
+
* Return `false` to skip the step; return nothing to continue.
|
|
343
|
+
*/
|
|
344
|
+
beforeShow?(ctx: StepContext): MaybePromise<undefined | false>;
|
|
345
|
+
afterShow?(ctx: StepContext): MaybePromise<void>;
|
|
346
|
+
beforeHide?(ctx: StepContext): MaybePromise<void>;
|
|
347
|
+
}
|
|
348
|
+
interface TourHooks {
|
|
349
|
+
onStart?(tour: Tour): void;
|
|
350
|
+
onStepChange?(ctx: StepContext): void;
|
|
351
|
+
onComplete?(tour: Tour): void;
|
|
352
|
+
onSkip?(ctx: StepContext): void;
|
|
353
|
+
onAbort?(tour: Tour, reason: string): void;
|
|
354
|
+
/** Per-step hooks, keyed by step id. */
|
|
355
|
+
steps?: Record<string, StepHooks>;
|
|
356
|
+
}
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/engine/reducer.d.ts
|
|
359
|
+
type TourStatus = 'idle' | 'running' | 'paused' | 'completed' | 'skipped' | 'aborted';
|
|
360
|
+
interface EngineState {
|
|
361
|
+
status: TourStatus;
|
|
362
|
+
/** Index into `tour.steps`, or -1 when not running. */
|
|
363
|
+
index: number;
|
|
364
|
+
/** Indices of previously shown steps, oldest first. Drives `back`. */
|
|
365
|
+
history: number[];
|
|
366
|
+
/** Set when status is `aborted` or `paused`. */
|
|
367
|
+
reason?: string;
|
|
368
|
+
}
|
|
369
|
+
type EngineAction = {
|
|
370
|
+
type: 'start';
|
|
371
|
+
at?: number | string;
|
|
372
|
+
} | {
|
|
373
|
+
type: 'next';
|
|
374
|
+
} | {
|
|
375
|
+
type: 'back';
|
|
376
|
+
} | {
|
|
377
|
+
type: 'go';
|
|
378
|
+
to: number | string;
|
|
379
|
+
} | {
|
|
380
|
+
type: 'skip';
|
|
381
|
+
} | {
|
|
382
|
+
type: 'complete';
|
|
383
|
+
} | {
|
|
384
|
+
type: 'abort';
|
|
385
|
+
reason: string;
|
|
386
|
+
} | {
|
|
387
|
+
type: 'pause';
|
|
388
|
+
reason: string;
|
|
389
|
+
} | {
|
|
390
|
+
type: 'resume';
|
|
391
|
+
} | {
|
|
392
|
+
type: 'stepMissing';
|
|
393
|
+
} | {
|
|
394
|
+
type: 'stepSkipped';
|
|
395
|
+
};
|
|
396
|
+
interface EngineContext {
|
|
397
|
+
tour: Tour;
|
|
398
|
+
/** Whether the step at `index` may be shown right now. */
|
|
399
|
+
isEligible: (index: number) => boolean;
|
|
400
|
+
}
|
|
401
|
+
export declare const IDLE_STATE: EngineState;
|
|
402
|
+
export declare function resolveStepIndex(tour: Tour, ref: number | string): number;
|
|
403
|
+
/** First eligible index at or after `from` (or at or before, when `dir` is -1). -1 if none. */
|
|
404
|
+
export declare function findEligible(ctx: EngineContext, from: number, dir?: 1 | -1): number;
|
|
405
|
+
export declare function reduce(state: EngineState, action: EngineAction, ctx: EngineContext): EngineState;
|
|
406
|
+
export declare function isActive(state: EngineState): boolean;
|
|
407
|
+
export declare function isFinished(state: EngineState): boolean;
|
|
408
|
+
export declare function canGoBack(state: EngineState, ctx: EngineContext): boolean;
|
|
409
|
+
/** True when another eligible step follows. False on the last step. */
|
|
410
|
+
export declare function hasNext(state: EngineState, ctx: EngineContext): boolean;
|
|
411
|
+
interface Progress {
|
|
412
|
+
/** 1-based position of the current step. */
|
|
413
|
+
current: number;
|
|
414
|
+
total: number;
|
|
415
|
+
}
|
|
416
|
+
/** Position over all steps, ineligible ones included, so numbers stay stable. */
|
|
417
|
+
export declare function progress(state: EngineState, ctx: EngineContext): Progress;
|
|
418
|
+
//#endregion
|
|
419
|
+
//#region src/engine/renderer.d.ts
|
|
420
|
+
interface RenderActions {
|
|
421
|
+
next(): void;
|
|
422
|
+
back(): void;
|
|
423
|
+
skip(): void;
|
|
424
|
+
/** Jump to a step by id or index. */
|
|
425
|
+
goTo(step: number | string): void;
|
|
426
|
+
}
|
|
427
|
+
interface RenderContext {
|
|
428
|
+
tour: Tour;
|
|
429
|
+
step: Step;
|
|
430
|
+
index: number;
|
|
431
|
+
progress: Progress;
|
|
432
|
+
isFirst: boolean;
|
|
433
|
+
isLast: boolean;
|
|
434
|
+
canGoBack: boolean;
|
|
435
|
+
actions: RenderActions;
|
|
436
|
+
}
|
|
437
|
+
interface Renderer {
|
|
438
|
+
/** Synchronous presence check. Used for `element` conditions and missing-target handling. */
|
|
439
|
+
hasTarget(target: Target): boolean;
|
|
440
|
+
/**
|
|
441
|
+
* Wait up to `timeoutMs` for the target to appear. Resolve `true` when it does.
|
|
442
|
+
* Must resolve promptly (with `false`) when `signal` aborts.
|
|
443
|
+
*/
|
|
444
|
+
waitForTarget(target: Target, timeoutMs: number, signal: AbortSignal): Promise<boolean>;
|
|
445
|
+
/** Render the step. The renderer wires user gestures to `ctx.actions`. */
|
|
446
|
+
show(ctx: RenderContext): MaybePromise<void>;
|
|
447
|
+
/** Remove everything from screen. Called on finish and before each new step. */
|
|
448
|
+
hide(): MaybePromise<void>;
|
|
449
|
+
/** Current route path, when the platform has one. */
|
|
450
|
+
currentRoute?(): string;
|
|
451
|
+
}
|
|
452
|
+
//#endregion
|
|
453
|
+
//#region src/engine/controller.d.ts
|
|
454
|
+
interface ControllerOptions {
|
|
455
|
+
tour: Tour;
|
|
456
|
+
renderer: Renderer;
|
|
457
|
+
identity?: Identity;
|
|
458
|
+
storage?: StorageAdapter;
|
|
459
|
+
sink?: EventSink;
|
|
460
|
+
hooks?: TourHooks;
|
|
461
|
+
/** Predicates for `custom` conditions, by name. */
|
|
462
|
+
custom?: Record<string, CustomPredicate>;
|
|
463
|
+
/** Progress of other tours, for `tour` conditions. */
|
|
464
|
+
tourState?: (tourId: string) => TourProgressState;
|
|
465
|
+
/** How long `onMissing: 'wait'` waits when the step sets no `waitFor`. */
|
|
466
|
+
defaultWaitMs?: number;
|
|
467
|
+
now?: () => number;
|
|
468
|
+
}
|
|
469
|
+
type StateListener = (state: EngineState) => void;
|
|
470
|
+
export declare class TourController {
|
|
471
|
+
readonly tour: Tour;
|
|
472
|
+
private state;
|
|
473
|
+
private readonly renderer;
|
|
474
|
+
private readonly identity;
|
|
475
|
+
private readonly store;
|
|
476
|
+
private readonly sink;
|
|
477
|
+
private readonly hooks;
|
|
478
|
+
private readonly custom;
|
|
479
|
+
private readonly tourStateOf;
|
|
480
|
+
private readonly defaultWaitMs;
|
|
481
|
+
private readonly now;
|
|
482
|
+
private readonly listeners;
|
|
483
|
+
/** Bumped whenever an async flow must be abandoned. */
|
|
484
|
+
private generation;
|
|
485
|
+
private pendingAbort;
|
|
486
|
+
private pendingTimer;
|
|
487
|
+
constructor(options: ControllerOptions);
|
|
488
|
+
getState(): EngineState;
|
|
489
|
+
subscribe(listener: StateListener): () => void;
|
|
490
|
+
/** Start from the first eligible step, or from `at` (step id or index). */
|
|
491
|
+
start(at?: number | string): Promise<void>;
|
|
492
|
+
/** Start where the user left off, according to persisted progress. */
|
|
493
|
+
resume(): Promise<void>;
|
|
494
|
+
next(): Promise<void>;
|
|
495
|
+
back(): Promise<void>;
|
|
496
|
+
goTo(step: number | string): Promise<void>;
|
|
497
|
+
/** The user gave up on the tour (Skip button, close, Escape). */
|
|
498
|
+
skip(): Promise<void>;
|
|
499
|
+
abort(reason: string): Promise<void>;
|
|
500
|
+
/** Report a named application event. Advances a step waiting on it. */
|
|
501
|
+
notify(eventName: string): void;
|
|
502
|
+
/** Tell the controller the route changed. Pauses or resumes route-bound steps. */
|
|
503
|
+
routeChanged(): Promise<void>;
|
|
504
|
+
/** Stop everything and clear the screen without recording an outcome. */
|
|
505
|
+
destroy(): Promise<void>;
|
|
506
|
+
private isActive;
|
|
507
|
+
private currentStep;
|
|
508
|
+
private conditionEnv;
|
|
509
|
+
private context;
|
|
510
|
+
private stepOnRoute;
|
|
511
|
+
private dispatch;
|
|
512
|
+
private setState;
|
|
513
|
+
private stepContext;
|
|
514
|
+
private emit;
|
|
515
|
+
private persist;
|
|
516
|
+
private cancelPending;
|
|
517
|
+
/** Run `beforeHide` for the step being left, if any. */
|
|
518
|
+
private leaveCurrent;
|
|
519
|
+
private afterTransition;
|
|
520
|
+
private finish;
|
|
521
|
+
private showCurrent;
|
|
522
|
+
/** Resolve `true` when the target is present, waiting if the step allows it. */
|
|
523
|
+
private ensureTarget;
|
|
524
|
+
/** Set up automatic advancement for `delay` and `element` steps. */
|
|
525
|
+
private armAdvance;
|
|
526
|
+
private renderContext;
|
|
527
|
+
}
|
|
528
|
+
//#endregion
|
|
529
|
+
//#region src/engine/events.d.ts
|
|
530
|
+
interface EventInput {
|
|
531
|
+
tour: Tour;
|
|
532
|
+
identity: Identity;
|
|
533
|
+
stepIndex?: number;
|
|
534
|
+
now?: () => number;
|
|
535
|
+
}
|
|
536
|
+
export declare function createEvent(type: DocentEventType, input: EventInput): DocentEvent;
|
|
537
|
+
/** Sink that drops everything. Default when none is configured. */
|
|
538
|
+
export declare const NOOP_SINK: EventSink;
|
|
539
|
+
/** Fan out to several sinks. */
|
|
540
|
+
export declare function combineSinks(...sinks: EventSink[]): EventSink;
|
|
541
|
+
//#endregion
|
|
542
|
+
//#region src/engine/progress.d.ts
|
|
543
|
+
interface TourRecord {
|
|
544
|
+
tourId: string;
|
|
545
|
+
version: number;
|
|
546
|
+
state: TourProgressState;
|
|
547
|
+
/** Step to resume from when the tour was interrupted. */
|
|
548
|
+
stepId?: string;
|
|
549
|
+
/** Unix epoch milliseconds. */
|
|
550
|
+
updatedAt: number;
|
|
551
|
+
}
|
|
552
|
+
export declare const STORAGE_PREFIX = "docent:";
|
|
553
|
+
export declare function storageKey(tourId: string): string;
|
|
554
|
+
export declare function tourVersion(tour: Tour): number;
|
|
555
|
+
/** Whether a tour should be offered given what the user has already done. */
|
|
556
|
+
export declare function shouldShow(tour: Tour, record: TourRecord | null): boolean;
|
|
557
|
+
export declare class ProgressStore {
|
|
558
|
+
private readonly storage;
|
|
559
|
+
constructor(storage: StorageAdapter);
|
|
560
|
+
get(tourId: string): Promise<TourRecord | null>;
|
|
561
|
+
set(record: TourRecord): Promise<void>;
|
|
562
|
+
clear(tourId: string): Promise<void>;
|
|
563
|
+
}
|
|
564
|
+
/** In-memory adapter. Default when no storage is configured, and handy in tests. */
|
|
565
|
+
export declare function createMemoryStorage(): StorageAdapter;
|
|
566
|
+
//#endregion
|
|
567
|
+
//#region src/engine/route.d.ts
|
|
568
|
+
/**
|
|
569
|
+
* Route pattern matching for `route` triggers, conditions and step routes.
|
|
570
|
+
*
|
|
571
|
+
* Patterns are path globs:
|
|
572
|
+
* - `/settings` exact
|
|
573
|
+
* - `/users/:id` one segment (named for readability, value ignored)
|
|
574
|
+
* - `/users/*` one segment
|
|
575
|
+
* - `/docs/**` zero or more segments
|
|
576
|
+
*
|
|
577
|
+
* Query strings and hashes are ignored. Trailing slashes are tolerated.
|
|
578
|
+
*/
|
|
579
|
+
export declare function matchRoute(pattern: string, path: string): boolean;
|
|
580
|
+
//#endregion
|
|
581
|
+
export type { Advance, Alignment, Condition, ConditionEnv, ControllerOptions, CustomPredicate, DocentEvent, DocentEventType, EngineAction, EngineContext, EngineState, EventInput, EventSink, Frequency, Identity, Interaction, Labels, MaybePromise, Media, OnMissing, OverlayOptions, Placement, Progress, RenderActions, RenderContext, Renderer, SchemaVersion, ScrollOptions, Side, SpotlightOptions, StateListener, Step, StepButtons, StepContext, StepHooks, StorageAdapter, Target, TargetSpec, Theme, Tour, TourHooks, TourOptions, TourProgressState, TourRecord, TourSource, TourStatus, TraitOperator, TraitValue, Trigger };
|
|
582
|
+
//# sourceMappingURL=index.d.ts.map
|