vastlint-react 0.4.20

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 ADDED
@@ -0,0 +1,14 @@
1
+ # vastlint-react
2
+
3
+ Headless React bindings for `vastlint-client`.
4
+
5
+ Current status:
6
+
7
+ - `useVastSession` is implemented as a thin hook over `vastlint-client` session instances.
8
+ - The hook subscribes to session snapshots, supports auto-load and auto-validate, and exposes tracking-aware session state.
9
+ - `useVastAnnotations` is implemented as a derived annotation model over `ValidationResult`, grouped by line and issue ID.
10
+ - `useVastPlayback` is implemented as a thin hook over `createVastPlaybackController()`, with subscribed playback snapshots, optional auto-initialize behavior, and bound playback lifecycle methods.
11
+ - `useVastPlaybackQueue` is implemented as a thin hook over `createVastPlaybackQueueController()`, with subscribed queue snapshots, optional auto-initialize behavior, and bound queue lifecycle methods.
12
+ - Build-first Node smoke tests now cover `useVastSession`, `useVastAnnotations`, `useVastTracker`, `useVastPlayback`, and `useVastPlaybackQueue` against built package output via a `jsdom` plus `react-dom/client` harness.
13
+ - `useVastTracker` is implemented as a thin hook over session tracking state and dispatch methods, including pod-aware `trackAd()` plus companion helpers for `getAdCompanions()`, `getCompanionTargets()`, and `trackCompanion()`.
14
+ - The package will stay renderer-agnostic and return data models rather than opinionated UI.
@@ -0,0 +1,6 @@
1
+ import type { UseVastAnnotationsOptions, UseVastPlaybackOptions, UseVastPlaybackQueueOptions, UseVastSessionOptions, UseVastTrackerOptions, VastAnnotationModel, VastPlaybackHookResult, VastPlaybackQueueHookResult, VastSessionHookResult, VastTrackerHookResult } from "./types.js";
2
+ export declare function useVastSession(options: UseVastSessionOptions): VastSessionHookResult;
3
+ export declare function useVastAnnotations(_options: UseVastAnnotationsOptions): VastAnnotationModel;
4
+ export declare function useVastPlayback(options: UseVastPlaybackOptions): VastPlaybackHookResult;
5
+ export declare function useVastPlaybackQueue(options: UseVastPlaybackQueueOptions): VastPlaybackQueueHookResult;
6
+ export declare function useVastTracker(options: UseVastTrackerOptions): VastTrackerHookResult;
package/dist/hooks.js ADDED
@@ -0,0 +1,431 @@
1
+ import { startTransition, useDeferredValue, useEffect, useMemo, useReducer, useRef } from "react";
2
+ import { createVastPlaybackController, createVastPlaybackQueueController, createVastSession, selectTrackingTargets } from "vastlint-client";
3
+ function useSubscribedSnapshot(store) {
4
+ const [, forceRender] = useReducer((value) => value + 1, 0);
5
+ const storeRef = useRef(store);
6
+ const snapshotRef = useRef(store.getSnapshot());
7
+ if (!Object.is(storeRef.current, store)) {
8
+ storeRef.current = store;
9
+ snapshotRef.current = store.getSnapshot();
10
+ }
11
+ useEffect(() => {
12
+ snapshotRef.current = store.getSnapshot();
13
+ let isSynchronousSubscription = true;
14
+ const unsubscribe = store.subscribe((nextSnapshot) => {
15
+ if (isSynchronousSubscription) {
16
+ return;
17
+ }
18
+ snapshotRef.current = nextSnapshot;
19
+ forceRender();
20
+ });
21
+ isSynchronousSubscription = false;
22
+ return unsubscribe;
23
+ }, [store]);
24
+ return snapshotRef.current;
25
+ }
26
+ function createEmptyAnnotationModel() {
27
+ return {
28
+ annotations: [],
29
+ byLine: new Map(),
30
+ byIssueId: new Map(),
31
+ };
32
+ }
33
+ function countXmlLines(xml) {
34
+ if (!xml) {
35
+ return 0;
36
+ }
37
+ return xml.split(/\r\n?|\n/).length;
38
+ }
39
+ function buildVastAnnotationModel(xml, validation) {
40
+ if (!validation || validation.issues.length === 0) {
41
+ return createEmptyAnnotationModel();
42
+ }
43
+ const maxLine = countXmlLines(xml);
44
+ const annotations = validation.issues.map((issue, index) => {
45
+ const line = issue.line !== null && issue.line >= 1 && issue.line <= maxLine ? issue.line : null;
46
+ const col = line === null ? null : issue.col;
47
+ return {
48
+ id: `${issue.id}:${issue.path ?? "document"}:${line ?? 0}:${col ?? 0}:${index}`,
49
+ issueId: issue.id,
50
+ severity: issue.severity,
51
+ message: issue.message,
52
+ path: issue.path,
53
+ line,
54
+ col,
55
+ };
56
+ });
57
+ const byLine = new Map();
58
+ const byIssueId = new Map();
59
+ for (const annotation of annotations) {
60
+ if (annotation.line !== null) {
61
+ const lineAnnotations = byLine.get(annotation.line) ?? [];
62
+ lineAnnotations.push(annotation);
63
+ byLine.set(annotation.line, lineAnnotations);
64
+ }
65
+ const issueAnnotations = byIssueId.get(annotation.issueId) ?? [];
66
+ issueAnnotations.push(annotation);
67
+ byIssueId.set(annotation.issueId, issueAnnotations);
68
+ }
69
+ return {
70
+ annotations,
71
+ byLine,
72
+ byIssueId,
73
+ };
74
+ }
75
+ function serializeValidateOptions(validateOptions) {
76
+ if (!validateOptions) {
77
+ return "";
78
+ }
79
+ const sortedRuleOverrides = validateOptions.rule_overrides
80
+ ? Object.fromEntries(Object.entries(validateOptions.rule_overrides).sort(([left], [right]) => left.localeCompare(right)))
81
+ : undefined;
82
+ return JSON.stringify({
83
+ wrapper_depth: validateOptions.wrapper_depth ?? null,
84
+ max_wrapper_depth: validateOptions.max_wrapper_depth ?? null,
85
+ rule_overrides: sortedRuleOverrides ?? null,
86
+ });
87
+ }
88
+ function serializeMediaSelectionOptions(mediaSelection) {
89
+ if (!mediaSelection) {
90
+ return "";
91
+ }
92
+ return JSON.stringify({
93
+ supportedMimeTypes: mediaSelection.supportedMimeTypes ?? null,
94
+ preferredMimeTypes: mediaSelection.preferredMimeTypes ?? null,
95
+ preferredDelivery: mediaSelection.preferredDelivery ?? null,
96
+ targetBitrate: mediaSelection.targetBitrate ?? null,
97
+ maxBitrate: mediaSelection.maxBitrate ?? null,
98
+ targetWidth: mediaSelection.targetWidth ?? null,
99
+ targetHeight: mediaSelection.targetHeight ?? null,
100
+ });
101
+ }
102
+ function createSessionConfig(options) {
103
+ return {
104
+ sourceKind: options.source.kind,
105
+ sourceValue: options.source.kind === "xml" ? options.source.xml : options.source.url,
106
+ label: options.source.label ?? null,
107
+ requestRef: options.source.kind === "url" ? (options.source.request ?? null) : null,
108
+ fetchRef: options.fetch ?? null,
109
+ timeoutMs: options.timeoutMs ?? null,
110
+ maxWrapperDepth: options.maxWrapperDepth ?? null,
111
+ validateOptionsKey: serializeValidateOptions(options.validateOptions),
112
+ };
113
+ }
114
+ function createPlaybackConfig(options) {
115
+ return {
116
+ sessionRef: options.session,
117
+ autoResolve: options.autoResolve !== false,
118
+ mediaSelectionKey: serializeMediaSelectionOptions(options.mediaSelection),
119
+ };
120
+ }
121
+ function createPlaybackQueueConfig(options) {
122
+ return {
123
+ sessionRef: options.session,
124
+ fetchRef: options.fetch ?? null,
125
+ autoResolve: options.autoResolve !== false,
126
+ mediaSelectionKey: serializeMediaSelectionOptions(options.mediaSelection),
127
+ };
128
+ }
129
+ function hasSessionConfigChanged(previous, next) {
130
+ return (previous.sourceKind !== next.sourceKind
131
+ || previous.sourceValue !== next.sourceValue
132
+ || previous.label !== next.label
133
+ || !Object.is(previous.requestRef, next.requestRef)
134
+ || !Object.is(previous.fetchRef, next.fetchRef)
135
+ || previous.timeoutMs !== next.timeoutMs
136
+ || previous.maxWrapperDepth !== next.maxWrapperDepth
137
+ || previous.validateOptionsKey !== next.validateOptionsKey);
138
+ }
139
+ function hasPlaybackConfigChanged(previous, next) {
140
+ return (!Object.is(previous.sessionRef, next.sessionRef)
141
+ || previous.autoResolve !== next.autoResolve
142
+ || previous.mediaSelectionKey !== next.mediaSelectionKey);
143
+ }
144
+ function hasPlaybackQueueConfigChanged(previous, next) {
145
+ return (!Object.is(previous.sessionRef, next.sessionRef)
146
+ || !Object.is(previous.fetchRef, next.fetchRef)
147
+ || previous.autoResolve !== next.autoResolve
148
+ || previous.mediaSelectionKey !== next.mediaSelectionKey);
149
+ }
150
+ async function runAutoAction(session, autoLoad, autoValidate) {
151
+ if (autoValidate) {
152
+ await session.validate();
153
+ return session.getSnapshot();
154
+ }
155
+ if (autoLoad) {
156
+ return session.load();
157
+ }
158
+ return session.getSnapshot();
159
+ }
160
+ export function useVastSession(options) {
161
+ const { autoLoad = true, autoValidate = false, ...sessionOptions } = options;
162
+ const [, forceRender] = useReducer((value) => value + 1, 0);
163
+ const trackedSessionRef = useRef(null);
164
+ const autoStartedSessionsRef = useRef(new WeakSet());
165
+ const sessionConfig = createSessionConfig(sessionOptions);
166
+ if (!trackedSessionRef.current
167
+ || hasSessionConfigChanged(trackedSessionRef.current.config, sessionConfig)) {
168
+ trackedSessionRef.current = {
169
+ config: sessionConfig,
170
+ session: createVastSession(sessionOptions),
171
+ };
172
+ }
173
+ const getCurrentSession = () => trackedSessionRef.current.session;
174
+ const replaceSession = () => {
175
+ const nextSession = createVastSession(sessionOptions);
176
+ trackedSessionRef.current = {
177
+ config: sessionConfig,
178
+ session: nextSession,
179
+ };
180
+ startTransition(() => {
181
+ forceRender();
182
+ });
183
+ return nextSession;
184
+ };
185
+ const session = getCurrentSession();
186
+ const snapshot = useSubscribedSnapshot(session);
187
+ useEffect(() => {
188
+ if ((!autoLoad && !autoValidate) || autoStartedSessionsRef.current.has(session)) {
189
+ return;
190
+ }
191
+ autoStartedSessionsRef.current.add(session);
192
+ void runAutoAction(session, autoLoad, autoValidate).catch(() => {
193
+ // Session state already captures errors for consumers.
194
+ });
195
+ }, [session, autoLoad, autoValidate]);
196
+ return {
197
+ session,
198
+ snapshot,
199
+ load() {
200
+ return getCurrentSession().load();
201
+ },
202
+ reload() {
203
+ const nextSession = replaceSession();
204
+ autoStartedSessionsRef.current.add(nextSession);
205
+ return runAutoAction(nextSession, true, autoValidate);
206
+ },
207
+ validate() {
208
+ return getCurrentSession().validate();
209
+ },
210
+ fix() {
211
+ return getCurrentSession().fix();
212
+ },
213
+ resolve() {
214
+ return getCurrentSession().resolve();
215
+ },
216
+ track(event, trackOptions) {
217
+ return getCurrentSession().track(event, trackOptions);
218
+ },
219
+ trackAd(adSelector, event, trackOptions) {
220
+ return getCurrentSession().trackAd(adSelector, event, trackOptions);
221
+ },
222
+ };
223
+ }
224
+ export function useVastAnnotations(_options) {
225
+ const deferredXml = useDeferredValue(_options.xml);
226
+ const deferredValidation = useDeferredValue(_options.validation);
227
+ return useMemo(() => buildVastAnnotationModel(deferredXml, deferredValidation), [deferredXml, deferredValidation]);
228
+ }
229
+ export function useVastPlayback(options) {
230
+ const { autoInitialize = true, ...controllerOptions } = options;
231
+ const trackedPlaybackRef = useRef(null);
232
+ const autoInitializedControllersRef = useRef(new WeakSet());
233
+ const playbackConfig = createPlaybackConfig(controllerOptions);
234
+ if (!trackedPlaybackRef.current
235
+ || hasPlaybackConfigChanged(trackedPlaybackRef.current.config, playbackConfig)) {
236
+ trackedPlaybackRef.current = {
237
+ config: playbackConfig,
238
+ controller: createVastPlaybackController(controllerOptions),
239
+ };
240
+ }
241
+ const getCurrentController = () => trackedPlaybackRef.current.controller;
242
+ const controller = getCurrentController();
243
+ const snapshot = useSubscribedSnapshot(controller);
244
+ useEffect(() => {
245
+ return () => {
246
+ controller.dispose();
247
+ };
248
+ }, [controller]);
249
+ useEffect(() => {
250
+ if (!autoInitialize || autoInitializedControllersRef.current.has(controller)) {
251
+ return;
252
+ }
253
+ autoInitializedControllersRef.current.add(controller);
254
+ void controller.initialize().catch(() => {
255
+ // Controller state already captures errors for consumers.
256
+ });
257
+ }, [controller, autoInitialize]);
258
+ return {
259
+ controller,
260
+ snapshot,
261
+ initialize() {
262
+ return getCurrentController().initialize();
263
+ },
264
+ start() {
265
+ return getCurrentController().start();
266
+ },
267
+ pause() {
268
+ return getCurrentController().pause();
269
+ },
270
+ resume() {
271
+ return getCurrentController().resume();
272
+ },
273
+ updateProgress(currentTimeSec, durationSec) {
274
+ return getCurrentController().updateProgress(currentTimeSec, durationSec);
275
+ },
276
+ complete() {
277
+ return getCurrentController().complete();
278
+ },
279
+ setMuted(muted) {
280
+ return getCurrentController().setMuted(muted);
281
+ },
282
+ setFullscreen(fullscreen) {
283
+ return getCurrentController().setFullscreen(fullscreen);
284
+ },
285
+ setViewability(viewability) {
286
+ return getCurrentController().setViewability(viewability);
287
+ },
288
+ click(trackOptions) {
289
+ return getCurrentController().click(trackOptions);
290
+ },
291
+ skip() {
292
+ return getCurrentController().skip();
293
+ },
294
+ signalError(trackOptions) {
295
+ return getCurrentController().signalError(trackOptions);
296
+ },
297
+ };
298
+ }
299
+ export function useVastPlaybackQueue(options) {
300
+ const { autoInitialize = true, ...controllerOptions } = options;
301
+ const trackedPlaybackQueueRef = useRef(null);
302
+ const autoInitializedControllersRef = useRef(new WeakSet());
303
+ const playbackQueueConfig = createPlaybackQueueConfig(controllerOptions);
304
+ if (!trackedPlaybackQueueRef.current
305
+ || hasPlaybackQueueConfigChanged(trackedPlaybackQueueRef.current.config, playbackQueueConfig)) {
306
+ trackedPlaybackQueueRef.current = {
307
+ config: playbackQueueConfig,
308
+ controller: createVastPlaybackQueueController(controllerOptions),
309
+ };
310
+ }
311
+ const getCurrentController = () => trackedPlaybackQueueRef.current.controller;
312
+ const controller = getCurrentController();
313
+ const snapshot = useSubscribedSnapshot(controller);
314
+ useEffect(() => {
315
+ return () => {
316
+ controller.dispose();
317
+ };
318
+ }, [controller]);
319
+ useEffect(() => {
320
+ if (!autoInitialize || autoInitializedControllersRef.current.has(controller)) {
321
+ return;
322
+ }
323
+ autoInitializedControllersRef.current.add(controller);
324
+ void controller.initialize().catch(() => {
325
+ // Controller state already captures errors for consumers.
326
+ });
327
+ }, [controller, autoInitialize]);
328
+ return {
329
+ controller,
330
+ snapshot,
331
+ initialize() {
332
+ return getCurrentController().initialize();
333
+ },
334
+ start() {
335
+ return getCurrentController().start();
336
+ },
337
+ pause() {
338
+ return getCurrentController().pause();
339
+ },
340
+ resume() {
341
+ return getCurrentController().resume();
342
+ },
343
+ updateProgress(currentTimeSec, durationSec) {
344
+ return getCurrentController().updateProgress(currentTimeSec, durationSec);
345
+ },
346
+ completeCurrent() {
347
+ return getCurrentController().completeCurrent();
348
+ },
349
+ next() {
350
+ return getCurrentController().next();
351
+ },
352
+ setMuted(muted) {
353
+ return getCurrentController().setMuted(muted);
354
+ },
355
+ setFullscreen(fullscreen) {
356
+ return getCurrentController().setFullscreen(fullscreen);
357
+ },
358
+ setViewability(viewability) {
359
+ return getCurrentController().setViewability(viewability);
360
+ },
361
+ click(trackOptions) {
362
+ return getCurrentController().click(trackOptions);
363
+ },
364
+ skip() {
365
+ return getCurrentController().skip();
366
+ },
367
+ signalError(trackOptions) {
368
+ return getCurrentController().signalError(trackOptions);
369
+ },
370
+ };
371
+ }
372
+ export function useVastTracker(options) {
373
+ const { session } = options;
374
+ const snapshot = useSubscribedSnapshot(session);
375
+ const availableEvents = useMemo(() => {
376
+ const events = new Set();
377
+ if (snapshot.tracking.plan.impressions.length > 0) {
378
+ events.add("impression");
379
+ }
380
+ if (snapshot.tracking.plan.errors.length > 0) {
381
+ events.add("error");
382
+ }
383
+ if (snapshot.tracking.plan.clickTrackings.length > 0) {
384
+ events.add("clickTracking");
385
+ }
386
+ for (const target of snapshot.tracking.plan.events) {
387
+ events.add(target.event);
388
+ }
389
+ return [...events].sort((left, right) => left.localeCompare(right));
390
+ }, [snapshot.tracking]);
391
+ return {
392
+ session,
393
+ tracking: snapshot.tracking,
394
+ resolvedAd: snapshot.resolvedAd,
395
+ resolvedAds: snapshot.resolvedAds,
396
+ companions: snapshot.resolvedAd?.companions ?? [],
397
+ availableEvents,
398
+ clickThroughUrl: snapshot.resolvedAd?.clickThroughUrl ?? null,
399
+ clickThroughUrls: snapshot.resolvedAd?.clickThroughUrls ?? [],
400
+ getAdCompanions(adSelector) {
401
+ return session.getAdCompanions(adSelector);
402
+ },
403
+ track(event, trackOptions) {
404
+ return session.track(event, trackOptions);
405
+ },
406
+ trackAd(adSelector, event, trackOptions) {
407
+ return session.trackAd(adSelector, event, trackOptions);
408
+ },
409
+ trackCompanion(adSelector, companionSelector, event, trackOptions) {
410
+ return session.trackCompanion(adSelector, companionSelector, event, trackOptions);
411
+ },
412
+ getTargets(event, trackOptions) {
413
+ return selectTrackingTargets(snapshot.tracking.plan, event, trackOptions?.offset);
414
+ },
415
+ getAdTargets(adSelector, event, trackOptions) {
416
+ return session.getAdTrackingTargets(adSelector, event, trackOptions);
417
+ },
418
+ getCompanionTargets(adSelector, companionSelector, event) {
419
+ return session.getCompanionTrackingTargets(adSelector, companionSelector, event);
420
+ },
421
+ hasTargets(event, trackOptions) {
422
+ return selectTrackingTargets(snapshot.tracking.plan, event, trackOptions?.offset).length > 0;
423
+ },
424
+ hasAdTargets(adSelector, event, trackOptions) {
425
+ return session.getAdTrackingTargets(adSelector, event, trackOptions).length > 0;
426
+ },
427
+ hasCompanionTargets(adSelector, companionSelector, event) {
428
+ return session.getCompanionTrackingTargets(adSelector, companionSelector, event).length > 0;
429
+ },
430
+ };
431
+ }
@@ -0,0 +1,2 @@
1
+ export { useVastAnnotations, useVastPlayback, useVastPlaybackQueue, useVastSession, useVastTracker } from "./hooks.js";
2
+ export type { UseVastAnnotationsOptions, UseVastPlaybackOptions, UseVastPlaybackQueueOptions, UseVastSessionOptions, UseVastTrackerOptions, VastAnnotation, VastAnnotationModel, VastPlaybackHookResult, VastPlaybackQueueHookResult, VastSessionHookResult, VastTrackerHookResult, } from "./types.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { useVastAnnotations, useVastPlayback, useVastPlaybackQueue, useVastSession, useVastTracker } from "./hooks.js";
@@ -0,0 +1,72 @@
1
+ import type { VastPlaybackController, VastPlaybackControllerOptions, VastPlaybackSnapshot, VastPlaybackQueueController, VastPlaybackQueueControllerOptions, VastPlaybackQueueSnapshot, VastCompanionAd, VastCompanionSelector, VastAdSelector, VastResolvedAd, VastSession, VastSessionOptions, VastSessionSnapshot, VastTrackOptions, VastTrackableEvent, VastTrackingDispatchResult, VastTrackingState, VastTrackingTarget } from "vastlint-client";
2
+ import type { FixResult, ValidationResult } from "vastlint";
3
+ export interface UseVastSessionOptions extends VastSessionOptions {
4
+ autoLoad?: boolean;
5
+ autoValidate?: boolean;
6
+ }
7
+ export interface VastAnnotation {
8
+ id: string;
9
+ issueId: string;
10
+ severity: "error" | "warning" | "info";
11
+ message: string;
12
+ path: string | null;
13
+ line: number | null;
14
+ col: number | null;
15
+ }
16
+ export interface VastAnnotationModel {
17
+ annotations: VastAnnotation[];
18
+ byLine: Map<number, VastAnnotation[]>;
19
+ byIssueId: Map<string, VastAnnotation[]>;
20
+ }
21
+ export interface UseVastAnnotationsOptions {
22
+ xml: string;
23
+ validation: ValidationResult | null;
24
+ }
25
+ export interface UseVastTrackerOptions {
26
+ session: VastSession;
27
+ }
28
+ export interface UseVastPlaybackOptions extends VastPlaybackControllerOptions {
29
+ autoInitialize?: boolean;
30
+ }
31
+ export interface UseVastPlaybackQueueOptions extends VastPlaybackQueueControllerOptions {
32
+ autoInitialize?: boolean;
33
+ }
34
+ export interface VastTrackerHookResult {
35
+ session: VastSession;
36
+ tracking: VastTrackingState;
37
+ resolvedAd: VastResolvedAd | null;
38
+ resolvedAds: VastResolvedAd[];
39
+ companions: VastCompanionAd[];
40
+ availableEvents: VastTrackableEvent[];
41
+ clickThroughUrl: string | null;
42
+ clickThroughUrls: string[];
43
+ getAdCompanions(adSelector: VastAdSelector): VastCompanionAd[];
44
+ track(event: VastTrackableEvent, options?: VastTrackOptions): Promise<VastTrackingDispatchResult[]>;
45
+ trackAd(adSelector: VastAdSelector, event: VastTrackableEvent, options?: VastTrackOptions): Promise<VastTrackingDispatchResult[]>;
46
+ trackCompanion(adSelector: VastAdSelector, companionSelector: VastCompanionSelector, event: VastTrackableEvent, options?: VastTrackOptions): Promise<VastTrackingDispatchResult[]>;
47
+ getTargets(event: VastTrackableEvent, options?: Pick<VastTrackOptions, "offset">): VastTrackingTarget[];
48
+ getAdTargets(adSelector: VastAdSelector, event: VastTrackableEvent, options?: Pick<VastTrackOptions, "offset">): VastTrackingTarget[];
49
+ getCompanionTargets(adSelector: VastAdSelector, companionSelector: VastCompanionSelector, event: VastTrackableEvent): VastTrackingTarget[];
50
+ hasTargets(event: VastTrackableEvent, options?: Pick<VastTrackOptions, "offset">): boolean;
51
+ hasAdTargets(adSelector: VastAdSelector, event: VastTrackableEvent, options?: Pick<VastTrackOptions, "offset">): boolean;
52
+ hasCompanionTargets(adSelector: VastAdSelector, companionSelector: VastCompanionSelector, event: VastTrackableEvent): boolean;
53
+ }
54
+ export interface VastSessionHookResult {
55
+ session: VastSession;
56
+ snapshot: VastSessionSnapshot;
57
+ load(): Promise<VastSessionSnapshot>;
58
+ reload(): Promise<VastSessionSnapshot>;
59
+ validate(): Promise<ValidationResult>;
60
+ fix(): Promise<FixResult>;
61
+ resolve(): Promise<VastSessionSnapshot>;
62
+ track(event: VastTrackableEvent, options?: VastTrackOptions): Promise<VastTrackingDispatchResult[]>;
63
+ trackAd(adSelector: VastAdSelector, event: VastTrackableEvent, options?: VastTrackOptions): Promise<VastTrackingDispatchResult[]>;
64
+ }
65
+ export interface VastPlaybackHookResult extends Pick<VastPlaybackController, "initialize" | "start" | "pause" | "resume" | "updateProgress" | "complete" | "setMuted" | "setFullscreen" | "setViewability" | "click" | "skip" | "signalError"> {
66
+ controller: VastPlaybackController;
67
+ snapshot: VastPlaybackSnapshot;
68
+ }
69
+ export interface VastPlaybackQueueHookResult extends Pick<VastPlaybackQueueController, "initialize" | "start" | "pause" | "resume" | "updateProgress" | "completeCurrent" | "next" | "setMuted" | "setFullscreen" | "setViewability" | "click" | "skip" | "signalError"> {
70
+ controller: VastPlaybackQueueController;
71
+ snapshot: VastPlaybackQueueSnapshot;
72
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "vastlint-react",
3
+ "version": "0.4.20",
4
+ "description": "Headless React hooks for vastlint-client.",
5
+ "license": "Apache-2.0",
6
+ "author": "Alex Sekowski <alex@vastlint.org>",
7
+ "homepage": "https://vastlint.org",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/aleksUIX/vastlint.git",
11
+ "directory": "packages/vastlint-react"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/aleksUIX/vastlint/issues"
15
+ },
16
+ "keywords": [
17
+ "vast",
18
+ "vast-client",
19
+ "react",
20
+ "react-hooks",
21
+ "adtech",
22
+ "ctv",
23
+ "video",
24
+ "advertising",
25
+ "programmatic"
26
+ ],
27
+ "type": "module",
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js"
34
+ }
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "README.md"
39
+ ],
40
+ "scripts": {
41
+ "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json",
42
+ "typecheck": "tsc -p tsconfig.json --noEmit",
43
+ "test": "npm --prefix ../vastlint-client run build && npm run build && node --test test/**/*.test.mjs"
44
+ },
45
+ "engines": {
46
+ "node": ">=18"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
51
+ "dependencies": {
52
+ "vastlint-client": "^0.4.20"
53
+ },
54
+ "peerDependencies": {
55
+ "react": ">=18"
56
+ },
57
+ "devDependencies": {
58
+ "@types/react": "^19.0.0",
59
+ "jsdom": "^26.1.0",
60
+ "react": "^19.0.0",
61
+ "react-dom": "^19.2.6",
62
+ "typescript": "^5.9.3"
63
+ }
64
+ }