@timeback/caliper 0.1.5 → 0.1.6

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/dist/index.d.ts CHANGED
@@ -1,80 +1,1409 @@
1
+ import * as _timeback_internal_client_infra from '@timeback/internal-client-infra';
2
+ import { ClientConfig, TransportOnlyConfig, CaliperPaths, RequestOptions, PaginatedResponse, ProviderClientConfig, BaseTransportConfig, Paginator as Paginator$1, ListParams, ProviderRegistry, TimebackProvider, AuthCheckResult, BaseTransport } from '@timeback/internal-client-infra';
3
+ export { AuthCheckResult, EnvAuth, Environment, ExplicitAuth } from '@timeback/internal-client-infra';
4
+
1
5
  /**
2
- * Caliper Analytics client SDK for Timeback.
6
+ * Timeback Shared Primitives
3
7
  *
4
- * Caliper Analytics client SDK for Timeback.
8
+ * Core types used across multiple Timeback protocols.
9
+ *
10
+ * Organization:
11
+ * - Shared types (this file): Used by multiple protocols (Caliper, OneRoster, etc.)
12
+ * - Protocol-specific types: Live in their respective protocols/X/primitives.ts files
13
+ *
14
+ * What belongs here:
15
+ * - TimebackSubject - Used in OneRoster courses AND Caliper events
16
+ * - TimebackGrade - Used across OneRoster, Caliper, and QTI
17
+ * - IMSErrorResponse - IMS Global standard used by multiple 1EdTech protocols
18
+ *
19
+ * What doesn't belong here:
20
+ * - OneRoster-specific: protocols/oneroster/primitives.ts
21
+ * - QTI-specific: protocols/qti/primitives.ts
22
+ */
23
+
24
+ // ─────────────────────────────────────────────────────────────────────────────
25
+ // TIMEBACK SHARED TYPES
26
+ // ─────────────────────────────────────────────────────────────────────────────
27
+
28
+ /**
29
+ * Valid Timeback subject values.
30
+ * Used in OneRoster courses and Caliper events.
31
+ */
32
+ type TimebackSubject =
33
+ | 'Reading'
34
+ | 'Language'
35
+ | 'Vocabulary'
36
+ | 'Social Studies'
37
+ | 'Writing'
38
+ | 'Science'
39
+ | 'FastMath'
40
+ | 'Math'
41
+ | 'None'
42
+ | 'Other'
43
+
44
+ /**
45
+ * Timeback Profile Types
46
+ *
47
+ * First-class types for the Timeback Caliper profile, including
48
+ * ActivityCompletedEvent and TimeSpentEvent.
49
+ */
50
+
51
+
52
+
53
+ // ═══════════════════════════════════════════════════════════════════════════════
54
+ // TIMEBACK ACTIVITY CONTEXT
55
+ // ═══════════════════════════════════════════════════════════════════════════════
56
+
57
+ // ═══════════════════════════════════════════════════════════════════════════════
58
+ // TIMEBACK USER
59
+ // ═══════════════════════════════════════════════════════════════════════════════
60
+
61
+ /**
62
+ * User role in the Timeback platform.
63
+ */
64
+ type TimebackUserRole = 'student' | 'teacher' | 'admin' | 'guide'
65
+
66
+ /**
67
+ * Timeback user entity.
68
+ *
69
+ * Represents a user in the Timeback platform. The `id` should ideally be
70
+ * the OneRoster URL for the user when available.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const user: TimebackUser = {
75
+ * id: 'https://api.alpha-1edtech.ai/ims/oneroster/rostering/v1p2/users/123',
76
+ * type: 'TimebackUser',
77
+ * email: 'student@example.edu',
78
+ * name: 'Jane Doe',
79
+ * role: 'student',
80
+ * }
81
+ * ```
82
+ */
83
+ interface TimebackUser {
84
+ /** User identifier (IRI format, preferably OneRoster URL) */
85
+ id: string
86
+ /** Must be 'TimebackUser' */
87
+ type: 'TimebackUser'
88
+ /** User email address */
89
+ email: string
90
+ /** User display name */
91
+ name?: string
92
+ /** User role */
93
+ role?: TimebackUserRole
94
+ /** Additional custom attributes */
95
+ extensions?: Record<string, unknown>
96
+ /** Index signature for Caliper compatibility */
97
+ [key: string]: unknown
98
+ }
99
+
100
+ /**
101
+ * Application reference within activity context.
102
+ */
103
+ interface TimebackApp {
104
+ /** Application identifier (IRI format) */
105
+ id?: string
106
+ /** Application name */
107
+ name: string
108
+ /** Additional custom attributes */
109
+ extensions?: Record<string, unknown>
110
+ }
111
+
112
+ /**
113
+ * Course reference within activity context.
114
+ */
115
+ interface TimebackCourse {
116
+ /** Course identifier (IRI format, preferably OneRoster URL) */
117
+ id?: string
118
+ /** Course name */
119
+ name: string
120
+ /** Additional custom attributes */
121
+ extensions?: Record<string, unknown>
122
+ }
123
+
124
+ /**
125
+ * Activity reference within activity context.
126
+ */
127
+ interface TimebackActivity {
128
+ /** Activity identifier (IRI format) */
129
+ id?: string
130
+ /** Activity name */
131
+ name: string
132
+ /** Additional custom attributes */
133
+ extensions?: Record<string, unknown>
134
+ }
135
+
136
+ /**
137
+ * Timeback activity context.
138
+ *
139
+ * Represents the context where an event was recorded, including
140
+ * subject, application, course, and activity information.
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * const context: TimebackActivityContext = {
145
+ * id: 'https://myapp.example.com/activities/123',
146
+ * type: 'TimebackActivityContext',
147
+ * subject: 'Math',
148
+ * app: { name: 'My Learning App' },
149
+ * course: { name: 'Algebra 101' },
150
+ * activity: { name: 'Chapter 1 Quiz' },
151
+ * }
152
+ * ```
153
+ */
154
+ interface TimebackActivityContext {
155
+ /** Context identifier (IRI format) */
156
+ id: string
157
+ /** Must be 'TimebackActivityContext' */
158
+ type: 'TimebackActivityContext'
159
+ /** Subject area */
160
+ subject: TimebackSubject
161
+ /** Application where event was recorded */
162
+ app: TimebackApp
163
+ /** Course where event was recorded */
164
+ course?: TimebackCourse
165
+ /** Activity where event was recorded */
166
+ activity?: TimebackActivity
167
+ /** Whether to process this event */
168
+ process?: boolean
169
+ /** Index signature for Caliper compatibility */
170
+ [key: string]: unknown
171
+ }
172
+
173
+ // ═══════════════════════════════════════════════════════════════════════════════
174
+ // ACTIVITY METRICS
175
+ // ═══════════════════════════════════════════════════════════════════════════════
176
+
177
+ /**
178
+ * Types of activity metrics.
179
+ */
180
+ type ActivityMetricType =
181
+ | 'xpEarned'
182
+ | 'totalQuestions'
183
+ | 'correctQuestions'
184
+ | 'masteredUnits'
185
+
186
+ /**
187
+ * Individual activity metric.
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * const metric: TimebackActivityMetric = {
192
+ * type: 'correctQuestions',
193
+ * value: 8,
194
+ * }
195
+ * ```
196
+ */
197
+ interface TimebackActivityMetric {
198
+ /** Metric type */
199
+ type: ActivityMetricType
200
+ /** Metric value */
201
+ value: number
202
+ /** Additional custom attributes */
203
+ extensions?: Record<string, unknown>
204
+ }
205
+
206
+ /**
207
+ * Collection of activity metrics.
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * const metrics: TimebackActivityMetricsCollection = {
212
+ * id: 'https://myapp.example.com/metrics/123',
213
+ * type: 'TimebackActivityMetricsCollection',
214
+ * attempt: 1,
215
+ * items: [
216
+ * { type: 'totalQuestions', value: 10 },
217
+ * { type: 'correctQuestions', value: 8 },
218
+ * { type: 'xpEarned', value: 150 },
219
+ * ],
220
+ * extensions: { pctCompleteApp: 67 },
221
+ * }
222
+ * ```
223
+ */
224
+ interface TimebackActivityMetricsCollection {
225
+ /** Collection identifier (IRI format) */
226
+ id: string
227
+ /** Must be 'TimebackActivityMetricsCollection' */
228
+ type: 'TimebackActivityMetricsCollection'
229
+ /** Attempt number (1-based) */
230
+ attempt?: number
231
+ /** Array of metrics */
232
+ items: TimebackActivityMetric[]
233
+ /**
234
+ * Additional custom attributes.
235
+ *
236
+ * Common fields:
237
+ * - `pctCompleteApp`: App-defined course completion percentage (0–100)
238
+ */
239
+ extensions?: Record<string, unknown>
240
+ /** Index signature for Caliper compatibility */
241
+ [key: string]: unknown
242
+ }
243
+
244
+ // ═══════════════════════════════════════════════════════════════════════════════
245
+ // TIME SPENT METRICS
246
+ // ═══════════════════════════════════════════════════════════════════════════════
247
+
248
+ /**
249
+ * Types of time spent metrics.
250
+ */
251
+ type TimeSpentMetricType = 'active' | 'inactive' | 'waste' | 'unknown' | 'anti-pattern'
252
+
253
+ /**
254
+ * Individual time spent metric.
255
+ *
256
+ * @example
257
+ * ```typescript
258
+ * const metric: TimeSpentMetric = {
259
+ * type: 'active',
260
+ * value: 1800, // 30 minutes in seconds
261
+ * startDate: '2024-01-15T10:00:00Z',
262
+ * endDate: '2024-01-15T10:30:00Z',
263
+ * }
264
+ * ```
265
+ */
266
+ interface TimeSpentMetric {
267
+ /** Metric type */
268
+ type: TimeSpentMetricType
269
+ /** Time spent in seconds (max 86400 = 24 hours) */
270
+ value: number
271
+ /** Sub-type for additional categorization */
272
+ subType?: string
273
+ /** Start of the time period */
274
+ startDate?: string
275
+ /** End of the time period */
276
+ endDate?: string
277
+ /** Additional custom attributes */
278
+ extensions?: Record<string, unknown>
279
+ }
280
+
281
+ /**
282
+ * Collection of time spent metrics.
283
+ *
284
+ * @example
285
+ * ```typescript
286
+ * const metrics: TimebackTimeSpentMetricsCollection = {
287
+ * id: 'https://myapp.example.com/time-metrics/123',
288
+ * type: 'TimebackTimeSpentMetricsCollection',
289
+ * items: [
290
+ * { type: 'active', value: 1800 },
291
+ * { type: 'inactive', value: 300 },
292
+ * ],
293
+ * }
294
+ * ```
295
+ */
296
+ interface TimebackTimeSpentMetricsCollection {
297
+ /** Collection identifier (IRI format) */
298
+ id: string
299
+ /** Must be 'TimebackTimeSpentMetricsCollection' */
300
+ type: 'TimebackTimeSpentMetricsCollection'
301
+ /** Array of time spent metrics */
302
+ items: TimeSpentMetric[]
303
+ /** Additional custom attributes */
304
+ extensions?: Record<string, unknown>
305
+ /** Index signature for Caliper compatibility */
306
+ [key: string]: unknown
307
+ }
308
+
309
+ // ═══════════════════════════════════════════════════════════════════════════════
310
+ // TIMEBACK EVENTS
311
+ // ═══════════════════════════════════════════════════════════════════════════════
312
+
313
+ /**
314
+ * Base properties common to all Timeback events.
315
+ */
316
+ interface TimebackEventBase {
317
+ /** JSON-LD context */
318
+ '@context': 'http://purl.imsglobal.org/ctx/caliper/v1p2'
319
+ /** Unique identifier (URN UUID format) */
320
+ id: string
321
+ /** The user who performed the action */
322
+ actor: TimebackUser
323
+ /** The activity context */
324
+ object: TimebackActivityContext
325
+ /** ISO 8601 datetime when event occurred */
326
+ eventTime: string
327
+ /** Must be 'TimebackProfile' */
328
+ profile: 'TimebackProfile'
329
+ /** Application context (IRI or entity) */
330
+ edApp?: string | Record<string, unknown>
331
+ /** Target segment within object */
332
+ target?: string | Record<string, unknown>
333
+ /** Referring context */
334
+ referrer?: string | Record<string, unknown>
335
+ /** Organization/group context */
336
+ group?: string | Record<string, unknown>
337
+ /** User's membership/role */
338
+ membership?: string | Record<string, unknown>
339
+ /** Current user session */
340
+ session?: string | Record<string, unknown>
341
+ /** LTI session context */
342
+ federatedSession?: string | Record<string, unknown>
343
+ /** Additional custom attributes */
344
+ extensions?: Record<string, unknown>
345
+ }
346
+
347
+ /**
348
+ * Timeback Activity Completed Event.
349
+ *
350
+ * Records when a student completes an activity, along with performance metrics.
5
351
  *
6
352
  * @example
7
353
  * ```typescript
8
- * // Timeback Profile - Activity Completed (recommended)
9
- * import { CaliperClient } from '@timeback/caliper'
354
+ * const event: ActivityCompletedEvent = {
355
+ * '@context': 'http://purl.imsglobal.org/ctx/caliper/v1p2',
356
+ * id: 'urn:uuid:c51570e4-f8ed-4c18-bb3a-dfe51b2cc594',
357
+ * type: 'ActivityEvent',
358
+ * action: 'Completed',
359
+ * actor: {
360
+ * id: 'https://api.example.com/users/123',
361
+ * type: 'TimebackUser',
362
+ * email: 'student@example.edu',
363
+ * },
364
+ * object: {
365
+ * id: 'https://myapp.example.com/activities/456',
366
+ * type: 'TimebackActivityContext',
367
+ * subject: 'Math',
368
+ * app: { name: 'My Learning App' },
369
+ * },
370
+ * eventTime: '2024-01-15T14:30:00Z',
371
+ * profile: 'TimebackProfile',
372
+ * generated: {
373
+ * id: 'https://myapp.example.com/metrics/789',
374
+ * type: 'TimebackActivityMetricsCollection',
375
+ * items: [
376
+ * { type: 'totalQuestions', value: 10 },
377
+ * { type: 'correctQuestions', value: 8 },
378
+ * ],
379
+ * },
380
+ * }
381
+ * ```
382
+ */
383
+ interface ActivityCompletedEvent extends TimebackEventBase {
384
+ /** Must be 'ActivityEvent' */
385
+ type: 'ActivityEvent'
386
+ /** Must be 'Completed' */
387
+ action: 'Completed'
388
+ /** Activity metrics generated from this completion */
389
+ generated: TimebackActivityMetricsCollection
390
+ }
391
+
392
+ /**
393
+ * Timeback Time Spent Event.
394
+ *
395
+ * Records time spent on an activity, categorized by engagement type.
396
+ *
397
+ * @example
398
+ * ```typescript
399
+ * const event: TimeSpentEvent = {
400
+ * '@context': 'http://purl.imsglobal.org/ctx/caliper/v1p2',
401
+ * id: 'urn:uuid:d62681f5-g9fe-5d29-cc4b-efg62c3dd695',
402
+ * type: 'TimeSpentEvent',
403
+ * action: 'SpentTime',
404
+ * actor: {
405
+ * id: 'https://api.example.com/users/123',
406
+ * type: 'TimebackUser',
407
+ * email: 'student@example.edu',
408
+ * },
409
+ * object: {
410
+ * id: 'https://myapp.example.com/activities/456',
411
+ * type: 'TimebackActivityContext',
412
+ * subject: 'Reading',
413
+ * app: { name: 'My Learning App' },
414
+ * },
415
+ * eventTime: '2024-01-15T15:00:00Z',
416
+ * profile: 'TimebackProfile',
417
+ * generated: {
418
+ * id: 'https://myapp.example.com/time-metrics/789',
419
+ * type: 'TimebackTimeSpentMetricsCollection',
420
+ * items: [
421
+ * { type: 'active', value: 1800 },
422
+ * { type: 'inactive', value: 300 },
423
+ * ],
424
+ * },
425
+ * }
426
+ * ```
427
+ */
428
+ interface TimeSpentEvent extends TimebackEventBase {
429
+ /** Must be 'TimeSpentEvent' */
430
+ type: 'TimeSpentEvent'
431
+ /** Must be 'SpentTime' */
432
+ action: 'SpentTime'
433
+ /** Time spent metrics generated from this session */
434
+ generated: TimebackTimeSpentMetricsCollection
435
+ }
436
+
437
+ /**
438
+ * Union of all Timeback event types.
439
+ */
440
+ type TimebackEvent = ActivityCompletedEvent | TimeSpentEvent
441
+
442
+ /**
443
+ * Caliper Event Types
444
+ *
445
+ * Types for Caliper Analytics events and envelopes.
446
+ */
447
+
448
+
449
+
450
+ /**
451
+ * Supported Caliper profiles.
452
+ */
453
+ type CaliperProfile =
454
+ | 'AnnotationProfile'
455
+ | 'AssessmentProfile'
456
+ | 'ToolUseProfile'
457
+ | 'GeneralProfile'
458
+ | 'FeedbackProfile'
459
+ | 'MediaProfile'
460
+ | 'SurveyProfile'
461
+ | 'ResourceManagementProfile'
462
+ | 'ForumProfile'
463
+ | 'AssignableProfile'
464
+ | 'GradingProfile'
465
+ | 'ReadingProfile'
466
+ | 'SessionProfile'
467
+ | 'SearchProfile'
468
+ | 'ToolLaunchProfile'
469
+ | 'TimebackProfile'
470
+
471
+ /**
472
+ * Base Caliper entity - can be a URI string or an object with properties.
473
+ */
474
+ type CaliperEntity = string | { [key: string]: unknown }
475
+
476
+ /**
477
+ * Caliper actor entity (for sending events).
478
+ *
479
+ * Timeback API requires actors to have extensions.email.
480
+ */
481
+ interface CaliperActor {
482
+ /** Unique identifier (IRI format) */
483
+ id: string
484
+ /** Entity type (e.g., 'Person', 'TimebackUser') */
485
+ type: string
486
+ /** Extensions - email is required by Timeback API */
487
+ extensions: {
488
+ /** Actor's email address (required by Timeback) */
489
+ email: string
490
+ /** Additional extension properties */
491
+ [key: string]: unknown
492
+ }
493
+ }
494
+
495
+ /**
496
+ * Caliper Event.
497
+ *
498
+ * Represents a learning activity event conforming to IMS Caliper v1.2.
499
+ */
500
+ interface CaliperEvent {
501
+ /** JSON-LD context */
502
+ '@context'?: string
503
+ /** Unique identifier (URN UUID format) */
504
+ id: string
505
+ /** Event type */
506
+ type: string
507
+ /** The agent who initiated the event (string URL, CaliperActor, or TimebackUser) */
508
+ actor: string | CaliperActor | TimebackUser
509
+ /** The action or predicate */
510
+ action: string
511
+ /** The object of the interaction */
512
+ object: CaliperEntity
513
+ /** ISO 8601 datetime when event occurred */
514
+ eventTime: string
515
+ /** Profile governing interpretation */
516
+ profile: CaliperProfile
517
+ /** Application context */
518
+ edApp?: CaliperEntity
519
+ /** Entity generated as result */
520
+ generated?: CaliperEntity
521
+ /** Target segment within object */
522
+ target?: CaliperEntity
523
+ /** Referring context */
524
+ referrer?: CaliperEntity
525
+ /** Organization/group context */
526
+ group?: CaliperEntity
527
+ /** User's membership/role */
528
+ membership?: CaliperEntity
529
+ /** Current user session */
530
+ session?: CaliperEntity
531
+ /** LTI session context */
532
+ federatedSession?: CaliperEntity
533
+ /** Additional custom attributes */
534
+ extensions?: Record<string, unknown>
535
+ }
536
+
537
+ /**
538
+ * Caliper Envelope.
539
+ *
540
+ * Container for transmitting Caliper events to the API.
541
+ */
542
+ interface CaliperEnvelope {
543
+ /** Sensor identifier (IRI format) */
544
+ sensor: string
545
+ /** ISO 8601 datetime when data was sent */
546
+ sendTime: string
547
+ /** Caliper data version */
548
+ dataVersion: 'http://purl.imsglobal.org/ctx/caliper/v1p2'
549
+ /** Array of events or entities */
550
+ data: CaliperEvent[]
551
+ }
552
+
553
+ /**
554
+ * Result of sending events.
555
+ */
556
+ interface SendEventsResult {
557
+ /** Job ID for tracking async processing */
558
+ jobId: string
559
+ }
560
+
561
+ /**
562
+ * Individual event result from job completion.
563
+ */
564
+ interface EventResult {
565
+ /** Allocated internal ID */
566
+ allocatedId: string
567
+ /** External event ID */
568
+ externalId: string
569
+ }
570
+
571
+ /**
572
+ * Job status response.
573
+ */
574
+ interface JobStatus {
575
+ id: string
576
+ state: 'waiting' | 'active' | 'completed' | 'failed'
577
+ returnValue?: {
578
+ status: 'success' | 'error'
579
+ results: EventResult[]
580
+ }
581
+ processedOn?: string | null
582
+ }
583
+
584
+ /**
585
+ * Stored Caliper event (from list/get).
586
+ *
587
+ * This represents an event as returned by the API, which differs from the
588
+ * input CaliperEvent format. The API adds internal fields and transforms
589
+ * the original event ID to `externalId`.
590
+ *
591
+ * @remarks
592
+ * **API Docs Drift**: The official OpenAPI spec (caliper-api.yaml) does not
593
+ * accurately document this response structure. This type was derived from
594
+ * actual API responses. Key differences:
595
+ * - `id` is a number (internal DB ID), not a string
596
+ * - `externalId` contains the original URN UUID (use this for `get()` calls)
597
+ * - Response is wrapped in `{ events: StoredEvent[] }` for list, `{ event: StoredEvent }` for get
598
+ */
599
+ interface StoredEvent {
600
+ /** Internal numeric ID (allocated by the database) */
601
+ id: number
602
+ /** Original event ID (URN UUID format) - use this for get() calls */
603
+ externalId: string
604
+ /** Sensor that sent the event */
605
+ sensor: string
606
+ /** Event type (e.g., 'ActivityEvent', 'Event') */
607
+ type: string
608
+ /** Caliper profile (e.g., 'TimebackProfile') */
609
+ profile?: string
610
+ /** The action or predicate */
611
+ action: string
612
+ /** When the event occurred */
613
+ eventTime: string
614
+ /** When the event was sent */
615
+ sendTime: string
616
+ /** When the record was last updated */
617
+ updated_at: string | null
618
+ /** When the record was created */
619
+ created_at: string
620
+ /** When the record was deleted (soft delete) */
621
+ deleted_at: string | null
622
+ /** The agent who initiated the event */
623
+ actor: CaliperEntity
624
+ /** The object of the event */
625
+ object: CaliperEntity
626
+ /** Generated entity (e.g., result, score) */
627
+ generated?: CaliperEntity | null
628
+ /** Target entity */
629
+ target?: CaliperEntity | null
630
+ /** Referrer entity */
631
+ referrer?: CaliperEntity | null
632
+ /** EdApp entity */
633
+ edApp?: CaliperEntity | null
634
+ /** Group/organization entity */
635
+ group?: CaliperEntity | null
636
+ /** Membership entity */
637
+ membership?: CaliperEntity | null
638
+ /** Session entity */
639
+ session?: CaliperEntity | null
640
+ /** Federated session entity */
641
+ federatedSession?: CaliperEntity | null
642
+ /** Extension data */
643
+ extensions?: Record<string, unknown> | null
644
+ /** Client application ID */
645
+ clientAppId?: string | null
646
+ }
647
+
648
+ /**
649
+ * Result from listing events.
650
+ */
651
+ interface ListEventsResult {
652
+ events: StoredEvent[]
653
+ pagination: PaginationMeta
654
+ }
655
+
656
+ /**
657
+ * API Response Types
658
+ *
659
+ * Types for Caliper API responses.
660
+ *
661
+ * @remarks
662
+ * **IMPORTANT - API Docs Drift**: The official API documentation (caliper/response.yaml
663
+ * and caliper-api.yaml) does NOT accurately reflect actual API responses. The types
664
+ * in this file were derived from testing actual API responses. See individual type
665
+ * comments for specific discrepancies.
666
+ */
667
+
668
+
669
+
670
+ /**
671
+ * Pagination metadata returned by list endpoints.
672
+ */
673
+ interface PaginationMeta {
674
+ /** Total number of items across all pages */
675
+ total: number
676
+ /** Total number of pages */
677
+ totalPages: number
678
+ /** Current page number (1-indexed) */
679
+ currentPage: number
680
+ /** Number of items per page */
681
+ limit: number
682
+ }
683
+
684
+ /**
685
+ * Options for waitForCompletion polling.
686
+ */
687
+ interface WaitForCompletionOptions {
688
+ /** Maximum time to wait in milliseconds (default: 30000) */
689
+ timeoutMs?: number
690
+ /** Interval between status checks in milliseconds (default: 1000) */
691
+ pollIntervalMs?: number
692
+ }
693
+
694
+ /**
695
+ * Validation result from the validate endpoint.
696
+ */
697
+ interface ValidationResult {
698
+ /** Whether validation succeeded */
699
+ status: 'success' | 'error'
700
+ /** Human-readable message */
701
+ message?: string
702
+ /** Validation errors (if any) */
703
+ errors?: unknown
704
+ }
705
+
706
+ /**
707
+ * Client Configuration Types
708
+ *
709
+ * Configuration types for the Caliper client.
710
+ */
711
+
712
+ /**
713
+ * Transport interface for Caliper client.
714
+ *
715
+ * Extends base transport requirements with Caliper-specific paths.
716
+ * Required when using transport mode with CaliperClient.
717
+ */
718
+ interface CaliperTransportLike {
719
+ /** Base URL of the API */
720
+ baseUrl: string;
721
+ /** API path profiles for Caliper operations */
722
+ paths: CaliperPaths;
723
+ /** Make an authenticated request */
724
+ request<T>(path: string, options?: RequestOptions): Promise<T>;
725
+ /** Make a paginated request using body-based pagination */
726
+ requestPaginated<T>(path: string, options?: RequestOptions): Promise<PaginatedResponse<T>>;
727
+ }
728
+ /**
729
+ * Caliper client configuration options.
730
+ *
731
+ * Supports four modes:
732
+ * - **Provider mode**: `{ provider: TimebackProvider }` — pre-built provider with token sharing
733
+ * - **Environment mode**: `{ platform?, env, auth }` — Timeback hosted APIs
734
+ * - **Explicit mode**: `{ baseUrl, auth: { authUrl } }` — custom API URLs
735
+ * - **Transport mode**: `{ transport: CaliperTransportLike }` — custom transport with paths
736
+ *
737
+ * The `platform` field (in env mode) selects which Timeback implementation to use:
738
+ * - `'BEYOND_AI'` (default): BeyondAI's Timeback platform
739
+ * - `'LEARNWITH_AI'`: Samy's LearnWith.AI platform
740
+ */
741
+ type CaliperClientConfig = ClientConfig | TransportOnlyConfig<CaliperTransportLike> | ProviderClientConfig;
742
+ /**
743
+ * Configuration for Caliper transport.
744
+ */
745
+ type CaliperTransportConfig = BaseTransportConfig & {
746
+ /** API path profiles for Caliper operations */
747
+ paths: CaliperPaths;
748
+ };
749
+ /**
750
+ * Instance type of CaliperClient.
751
+ */
752
+ type CaliperClientInstance = InstanceType<typeof CaliperClient>;
753
+
754
+ /**
755
+ * Caliper Constants
756
+ *
757
+ * Configuration constants for the Caliper Analytics client.
758
+ */
759
+
760
+ /**
761
+ * Caliper JSON-LD context version.
762
+ */
763
+ declare const CALIPER_DATA_VERSION = "http://purl.imsglobal.org/ctx/caliper/v1p2";
764
+
765
+ type input<T> = T extends {
766
+ _zod: {
767
+ input: any;
768
+ };
769
+ } ? T["_zod"]["input"] : unknown;
770
+
771
+ /**
772
+ * Caliper Schemas
773
+ *
774
+ * Zod schemas for the IMS Caliper Analytics standard with Timeback Profile.
775
+ */
776
+
777
+
778
+
779
+ // ═══════════════════════════════════════════════════════════════════════════════
780
+ // BUILDER INPUTS
781
+ // ═══════════════════════════════════════════════════════════════════════════════
782
+
783
+ declare const ActivityCompletedInput = z
784
+ .object({
785
+ actor: TimebackUser,
786
+ object: TimebackActivityContext,
787
+ metrics: z.array(TimebackActivityMetric).min(1, 'metrics must contain at least one metric'),
788
+ eventTime: IsoDateTimeString.optional(),
789
+ metricsId: z.string().optional(),
790
+ id: z.string().optional(),
791
+ /** Event-level extensions */
792
+ extensions: z.record(z.string(), z.unknown()).optional(),
793
+ /**
794
+ * Application context (IRI or entity).
795
+ *
796
+ * Maps to `edApp` in the Caliper event. Identifies the educational
797
+ * application where the event occurred.
798
+ */
799
+ edApp: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
800
+ /**
801
+ * Session context (IRI or entity).
802
+ *
803
+ * Maps to `session` in the Caliper event. Used for event-to-session
804
+ * correlation (e.g., linking heartbeats with completions via runId).
805
+ */
806
+ session: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
807
+ /**
808
+ * Attempt number (1-based).
809
+ *
810
+ * Maps to `generated.attempt` in the Caliper event.
811
+ */
812
+ attempt: z.number().int().min(1).optional(),
813
+ /**
814
+ * Extensions for the generated metrics collection.
815
+ *
816
+ * Maps to `generated.extensions` in the Caliper event.
817
+ * Use `generatedExtensions.pctCompleteApp` (0–100) for app-reported course progress.
818
+ */
819
+ generatedExtensions: z
820
+ .object({
821
+ /**
822
+ * App-reported course progress (per enrollment), as a percentage from 0–100.
823
+ *
824
+ * This is emitted to Caliper as `generated.extensions.pctCompleteApp`.
825
+ *
826
+ * @remarks
827
+ * This value is not clamped here (Caliper client keeps the raw shape).
828
+ */
829
+ pctCompleteApp: z.number().optional(),
830
+ })
831
+ .loose()
832
+ .optional(),
833
+ })
834
+ .strict()
835
+
836
+ // ═══════════════════════════════════════════════════════════════════════════════
837
+ // TYPE EXPORTS (REQUEST INPUTS)
838
+ // ═══════════════════════════════════════════════════════════════════════════════
839
+
840
+ type ActivityCompletedInput = input<typeof ActivityCompletedInput>
841
+
842
+ declare const TimeSpentInput = z
843
+ .object({
844
+ actor: TimebackUser,
845
+ object: TimebackActivityContext,
846
+ metrics: z.array(TimebackTimeMetric).min(1, 'metrics must contain at least one metric'),
847
+ eventTime: IsoDateTimeString.optional(),
848
+ metricsId: z.string().optional(),
849
+ id: z.string().optional(),
850
+ extensions: z.record(z.string(), z.unknown()).optional(),
851
+ edApp: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
852
+ session: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
853
+ })
854
+ .strict()
855
+ type TimeSpentInput = input<typeof TimeSpentInput>
856
+
857
+ declare const CaliperListEventsParams = z
858
+ .object({
859
+ limit: z.number().int().positive().optional(),
860
+ offset: z.number().int().min(0).optional(),
861
+ sensor: z.string().min(1).optional(),
862
+ startDate: IsoDateTimeString.optional(),
863
+ endDate: IsoDateTimeString.optional(),
864
+ actorId: z.string().min(1).optional(),
865
+ actorEmail: z.email().optional(),
866
+ })
867
+ .strict()
868
+ type CaliperListEventsParams = input<typeof CaliperListEventsParams>
869
+
870
+ /**
871
+ * Pagination Utilities
10
872
  *
873
+ * Re-exports the common Paginator with Caliper-specific configuration.
874
+ */
875
+
876
+ /**
877
+ * Caliper-specific Paginator that uses the Caliper transport.
878
+ *
879
+ * Uses body-based pagination with the events response format.
880
+ *
881
+ * @typeParam T - The type of items being paginated
882
+ */
883
+ declare class Paginator<T> extends Paginator$1<T> {
884
+ /**
885
+ * Create a new Caliper Paginator.
886
+ *
887
+ * @param transport - Caliper transport instance
888
+ * @param path - API endpoint path
889
+ * @param params - List parameters including optional max
890
+ */
891
+ constructor(transport: CaliperTransportLike, path: string, params?: ListParams);
892
+ }
893
+
894
+ /**
895
+ * Events Resource
896
+ *
897
+ * Manage Caliper events - send, list, and retrieve.
898
+ */
899
+
900
+ /**
901
+ * Caliper Events resource.
902
+ *
903
+ * Provides methods to send, list, and retrieve Caliper events.
904
+ */
905
+ declare class EventsResource {
906
+ private readonly transport;
907
+ constructor(transport: CaliperTransportLike);
908
+ /**
909
+ * Send Caliper events.
910
+ *
911
+ * Wraps events in an envelope and sends to the API.
912
+ * Events are validated against the IMS Caliper specification
913
+ * and queued for async processing.
914
+ *
915
+ * @param sensor - Sensor identifier (IRI format)
916
+ * @param events - Array of Caliper events
917
+ * @returns Job ID for tracking processing status
918
+ *
919
+ * @remarks
920
+ * **API Response Drift**: The official API docs (caliper/response.yaml) document
921
+ * the response as `{ status, message, errors? }`, but the actual API returns
922
+ * `{ jobId }`. This client correctly handles the actual response.
923
+ *
924
+ * @example
925
+ * ```typescript
926
+ * const result = await client.events.send(
927
+ * 'https://example.edu/sensors/1',
928
+ * [event1, event2]
929
+ * )
930
+ * ```
931
+ */
932
+ send(sensor: string, events: CaliperEvent[]): Promise<SendEventsResult>;
933
+ /**
934
+ * Send a raw Caliper envelope.
935
+ *
936
+ * Use this when you need full control over the envelope structure.
937
+ * For most cases, prefer `send()` which builds the envelope for you.
938
+ *
939
+ * @param envelope - Caliper envelope containing events
940
+ * @returns Job ID for tracking processing status
941
+ *
942
+ * @remarks
943
+ * **API Response Drift**: See `send()` for details on response format drift.
944
+ *
945
+ * @example
946
+ * ```typescript
947
+ * const result = await client.events.sendEnvelope({
948
+ * sensor: 'https://example.edu/sensors/1',
949
+ * sendTime: new Date().toISOString(),
950
+ * dataVersion: 'http://purl.imsglobal.org/ctx/caliper/v1p2',
951
+ * data: [event1, event2],
952
+ * })
953
+ * ```
954
+ */
955
+ sendEnvelope(envelope: CaliperEnvelope): Promise<SendEventsResult>;
956
+ /**
957
+ * Validate Caliper events without storing them.
958
+ *
959
+ * Use this to check if events conform to the IMS Caliper specification
960
+ * before sending them for processing.
961
+ *
962
+ * @param envelope - Caliper envelope containing events to validate
963
+ * @returns Validation result with status and any errors
964
+ *
965
+ * @example
966
+ * ```typescript
967
+ * const result = await client.events.validate({
968
+ * sensor: 'https://example.edu/sensors/1',
969
+ * sendTime: new Date().toISOString(),
970
+ * dataVersion: 'http://purl.imsglobal.org/ctx/caliper/v1p2',
971
+ * data: [event1, event2],
972
+ * })
973
+ *
974
+ * if (result.status === 'success') {
975
+ * console.log('Events are valid!')
976
+ * } else {
977
+ * console.log('Validation errors:', result.errors)
978
+ * }
979
+ * ```
980
+ */
981
+ validate(envelope: CaliperEnvelope): Promise<ValidationResult>;
982
+ /**
983
+ * List Caliper events with optional filtering.
984
+ *
985
+ * @param params - Filter parameters
986
+ * @returns Events array and pagination metadata
987
+ *
988
+ * @remarks
989
+ * **API Response Drift**: The official API docs (caliper/response.yaml) document
990
+ * the response as `{ status, message, errors? }`, but the actual API returns
991
+ * `{ events: StoredEvent[], pagination: { total, totalPages, currentPage, limit } }`.
992
+ * This client correctly handles the actual response.
993
+ *
994
+ * @example
995
+ * ```typescript
996
+ * const { events } = await client.events.list({
997
+ * limit: 50,
998
+ * actorEmail: 'student@example.edu',
999
+ * startDate: '2024-01-01',
1000
+ * })
1001
+ *
1002
+ * // Access pagination metadata
1003
+ * const { events, pagination } = await client.events.list({ limit: 10 })
1004
+ * console.log(`Total: ${pagination.total}`)
1005
+ * ```
1006
+ */
1007
+ list(params?: CaliperListEventsParams): Promise<ListEventsResult>;
1008
+ /**
1009
+ * Stream Caliper events with automatic pagination.
1010
+ *
1011
+ * Returns a Paginator that lazily fetches pages as you iterate.
1012
+ * Use this for large datasets or when you need all matching events.
1013
+ *
1014
+ * @param params - Filter parameters (same as list())
1015
+ * @returns Paginator for async iteration
1016
+ *
1017
+ * @example
1018
+ * ```typescript
1019
+ * // Iterate over all events
1020
+ * for await (const event of client.events.stream({ startDate: '2024-01-01' })) {
1021
+ * console.log(event.id)
1022
+ * }
1023
+ * ```
1024
+ *
1025
+ * @example
1026
+ * ```typescript
1027
+ * // Collect all events into an array
1028
+ * const allEvents = await client.events
1029
+ * .stream({ startDate: '2024-01-01' })
1030
+ * .toArray()
1031
+ * ```
1032
+ *
1033
+ * @example
1034
+ * ```typescript
1035
+ * // Limit total events fetched
1036
+ * const events = await client.events
1037
+ * .stream({ startDate: '2024-01-01', max: 1000 })
1038
+ * .toArray()
1039
+ * ```
1040
+ */
1041
+ stream(params?: CaliperListEventsParams & {
1042
+ max?: number;
1043
+ }): Paginator<StoredEvent>;
1044
+ /**
1045
+ * Get a specific event by its external ID.
1046
+ *
1047
+ * @param externalId - The event's external ID (URN UUID format, e.g., 'urn:uuid:...')
1048
+ * @returns The stored event
1049
+ *
1050
+ * @remarks
1051
+ * **API Response Drift**: The official API docs (caliper/response.yaml) document
1052
+ * the response as `{ status, message, errors? }`, but the actual API returns
1053
+ * `{ status, event: StoredEvent }`. This client correctly handles the actual response.
1054
+ *
1055
+ * **Important**: Use `externalId` (URN UUID), not the internal numeric `id`.
1056
+ * The `StoredEvent` returned from `list()` contains both - use `event.externalId`.
1057
+ *
1058
+ * @example
1059
+ * ```typescript
1060
+ * const event = await client.events.get('urn:uuid:c51570e4-f8ed-4c18-bb3a-dfe51b2cc594')
1061
+ * ```
1062
+ */
1063
+ get(externalId: string): Promise<StoredEvent>;
1064
+ /**
1065
+ * Send an activity event (Timeback Profile).
1066
+ *
1067
+ * Records student activity completion with performance metrics.
1068
+ * This is a first-class method for the Timeback platform.
1069
+ *
1070
+ * @param sensor - Sensor identifier (IRI format)
1071
+ * @param input - Activity completion data
1072
+ * @returns Job ID for tracking processing status
1073
+ *
1074
+ * @example
1075
+ * ```typescript
1076
+ * const result = await client.events.sendActivity(
1077
+ * 'https://myapp.example.com/sensors/main',
1078
+ * {
1079
+ * actor: {
1080
+ * id: 'https://api.example.com/users/123',
1081
+ * type: 'TimebackUser',
1082
+ * email: 'student@example.edu',
1083
+ * },
1084
+ * object: {
1085
+ * id: 'https://myapp.example.com/activities/456',
1086
+ * type: 'TimebackActivityContext',
1087
+ * subject: 'Math',
1088
+ * app: { name: 'My Learning App' },
1089
+ * },
1090
+ * metrics: [
1091
+ * { type: 'totalQuestions', value: 10 },
1092
+ * { type: 'correctQuestions', value: 8 },
1093
+ * { type: 'xpEarned', value: 150 },
1094
+ * ],
1095
+ * },
1096
+ * )
1097
+ * ```
1098
+ */
1099
+ sendActivity(sensor: string, input: ActivityCompletedInput): Promise<SendEventsResult>;
1100
+ /**
1101
+ * Send a time spent event (Timeback Profile).
1102
+ *
1103
+ * Records time spent on an activity, categorized by engagement type.
1104
+ * This is a first-class method for the Timeback platform.
1105
+ *
1106
+ * @param sensor - Sensor identifier (IRI format)
1107
+ * @param input - Time spent data
1108
+ * @returns Job ID for tracking processing status
1109
+ *
1110
+ * @example
1111
+ * ```typescript
1112
+ * const result = await client.events.sendTimeSpent(
1113
+ * 'https://myapp.example.com/sensors/main',
1114
+ * {
1115
+ * actor: {
1116
+ * id: 'https://api.example.com/users/123',
1117
+ * type: 'TimebackUser',
1118
+ * email: 'student@example.edu',
1119
+ * },
1120
+ * object: {
1121
+ * id: 'https://myapp.example.com/activities/456',
1122
+ * type: 'TimebackActivityContext',
1123
+ * subject: 'Reading',
1124
+ * app: { name: 'My Learning App' },
1125
+ * },
1126
+ * metrics: [
1127
+ * { type: 'active', value: 1800 }, // 30 minutes
1128
+ * { type: 'inactive', value: 300 }, // 5 minutes
1129
+ * ],
1130
+ * },
1131
+ * )
1132
+ * ```
1133
+ */
1134
+ sendTimeSpent(sensor: string, input: TimeSpentInput): Promise<SendEventsResult>;
1135
+ }
1136
+
1137
+ /**
1138
+ * Jobs Resource
1139
+ *
1140
+ * Track status of async event processing jobs.
1141
+ */
1142
+
1143
+ /**
1144
+ * Jobs resource for tracking async processing.
1145
+ *
1146
+ * When events are submitted, they are queued for async processing.
1147
+ * Use this resource to check job status and retrieve results.
1148
+ */
1149
+ declare class JobsResource {
1150
+ private readonly transport;
1151
+ constructor(transport: CaliperTransportLike);
1152
+ /**
1153
+ * Get the status of a processing job.
1154
+ *
1155
+ * @param jobId - The job ID returned from events.send()
1156
+ * @returns Job status including state and results
1157
+ *
1158
+ * @example
1159
+ * ```typescript
1160
+ * const status = await client.jobs.getStatus(jobId)
1161
+ *
1162
+ * if (status.state === 'completed') {
1163
+ * console.log('Events processed:', status.returnValue?.results)
1164
+ * }
1165
+ * ```
1166
+ */
1167
+ getStatus(jobId: string): Promise<JobStatus>;
1168
+ /**
1169
+ * Wait for a job to complete with polling.
1170
+ *
1171
+ * @param jobId - The job ID to wait for
1172
+ * @param options - Polling options
1173
+ * @returns Final job status
1174
+ * @throws {Error} If job fails or times out
1175
+ *
1176
+ * @example
1177
+ * ```typescript
1178
+ * const result = await client.events.send(envelope)
1179
+ * const status = await client.jobs.waitForCompletion(result.jobId)
1180
+ * console.log('Processed events:', status.returnValue?.results)
1181
+ * ```
1182
+ */
1183
+ waitForCompletion(jobId: string, options?: WaitForCompletionOptions): Promise<JobStatus>;
1184
+ }
1185
+
1186
+ /**
1187
+ * Caliper Client
1188
+ *
1189
+ * Main entry point for the Caliper Analytics SDK.
1190
+ */
1191
+ /**
1192
+ * Caliper Analytics API client.
1193
+ *
1194
+ * Provides methods to send, list, and retrieve Caliper learning events,
1195
+ * as well as track async processing jobs.
1196
+ *
1197
+ * @example
1198
+ * ```typescript
1199
+ * // Environment mode (Timeback APIs)
11
1200
  * const client = new CaliperClient({
12
- * env: 'staging',
1201
+ * env: 'staging', // or 'production'
13
1202
  * auth: {
14
1203
  * clientId: 'your-client-id',
15
1204
  * clientSecret: 'your-client-secret',
16
1205
  * },
17
1206
  * })
1207
+ * ```
18
1208
  *
19
- * // Send activity completion with metrics
20
- * const result = await client.events.sendActivity(
21
- * 'https://myapp.example.com/sensors/main',
22
- * {
23
- * actor: {
24
- * id: 'https://api.example.com/users/123',
25
- * type: 'TimebackUser',
26
- * email: 'student@example.edu',
27
- * },
28
- * object: {
29
- * id: 'https://myapp.example.com/activities/456',
30
- * type: 'TimebackActivityContext',
31
- * subject: 'Math',
32
- * app: { name: 'My Learning App' },
33
- * },
34
- * metrics: [
35
- * { type: 'totalQuestions', value: 10 },
36
- * { type: 'correctQuestions', value: 8 },
37
- * { type: 'xpEarned', value: 150 },
38
- * ],
1209
+ * @example
1210
+ * ```typescript
1211
+ * // Provider mode (shared tokens)
1212
+ * import { TimebackProvider } from '@timeback/internal-client-infra'
1213
+ *
1214
+ * const provider = new TimebackProvider({
1215
+ * platform: 'BEYOND_AI',
1216
+ * env: 'staging',
1217
+ * auth: { clientId: '...', clientSecret: '...' },
1218
+ * })
1219
+ *
1220
+ * const client = new CaliperClient({ provider })
1221
+ * ```
1222
+ *
1223
+ * @example
1224
+ * ```typescript
1225
+ * // Explicit mode (custom API)
1226
+ * const client = new CaliperClient({
1227
+ * baseUrl: 'https://caliper.example.com',
1228
+ * auth: {
1229
+ * clientId: 'your-client-id',
1230
+ * clientSecret: 'your-client-secret',
1231
+ * authUrl: 'https://auth.example.com/oauth2/token',
39
1232
  * },
1233
+ * })
1234
+ * ```
1235
+ *
1236
+ * @example
1237
+ * ```typescript
1238
+ * // Environment variables fallback
1239
+ * // Set CALIPER_BASE_URL, CALIPER_TOKEN_URL,
1240
+ * // CALIPER_CLIENT_ID, CALIPER_CLIENT_SECRET
1241
+ * const client = new CaliperClient()
1242
+ * ```
1243
+ *
1244
+ * @example
1245
+ * ```typescript
1246
+ * // Sending events
1247
+ * const result = await client.events.send(
1248
+ * 'https://example.edu/sensors/lms',
1249
+ * [{
1250
+ * id: 'urn:uuid:...',
1251
+ * type: 'NavigationEvent',
1252
+ * actor: 'https://example.edu/users/123',
1253
+ * action: 'NavigatedTo',
1254
+ * object: 'https://example.edu/courses/456',
1255
+ * eventTime: new Date().toISOString(),
1256
+ * profile: 'GeneralProfile',
1257
+ * }]
40
1258
  * )
41
1259
  *
42
1260
  * // Wait for processing
43
1261
  * const status = await client.jobs.waitForCompletion(result.jobId)
44
1262
  * ```
1263
+ */
1264
+ declare const CaliperClient: {
1265
+ new (config?: CaliperClientConfig): {
1266
+ readonly transport: CaliperTransportLike;
1267
+ readonly _provider?: _timeback_internal_client_infra.TimebackProvider | undefined;
1268
+ readonly events: EventsResource;
1269
+ readonly jobs: JobsResource;
1270
+ getTransport(): CaliperTransportLike;
1271
+ checkAuth(): Promise<_timeback_internal_client_infra.AuthCheckResult>;
1272
+ };
1273
+ };
1274
+
1275
+ /**
1276
+ * Caliper Client Factory
1277
+ *
1278
+ * Creates CaliperClient classes bound to specific provider registries.
1279
+ */
1280
+
1281
+ /**
1282
+ * Create a CaliperClient class bound to a specific provider registry.
1283
+ *
1284
+ * @param registry - Provider registry to use (defaults to all Timeback platforms)
1285
+ * @returns CaliperClient class bound to the registry
1286
+ */
1287
+ declare function createCaliperClient(registry?: ProviderRegistry): {
1288
+ new (config?: CaliperClientConfig): {
1289
+ /** @internal */
1290
+ readonly transport: CaliperTransportLike;
1291
+ /** @internal */
1292
+ readonly _provider?: TimebackProvider | undefined;
1293
+ /** Send and query Caliper learning events for analytics and activity tracking */
1294
+ readonly events: EventsResource;
1295
+ /** Create and monitor batch event processing jobs for high-volume event ingestion */
1296
+ readonly jobs: JobsResource;
1297
+ /**
1298
+ * Get the underlying transport for advanced use cases.
1299
+ * @returns The transport instance used by this client
1300
+ */
1301
+ getTransport(): CaliperTransportLike;
1302
+ /**
1303
+ * Verify that OAuth authentication is working.
1304
+ * @returns Auth check result
1305
+ * @throws {Error} If client was initialized with custom transport (no provider)
1306
+ */
1307
+ checkAuth(): Promise<AuthCheckResult>;
1308
+ };
1309
+ };
1310
+
1311
+ /**
1312
+ * Event Factory Functions
1313
+ *
1314
+ * Pure factory functions for creating Timeback profile events.
1315
+ * Use these when you want to batch multiple events into a single envelope.
1316
+ */
1317
+
1318
+ /**
1319
+ * Create an ActivityEvent from input.
1320
+ *
1321
+ * Pure factory function - creates the event object without sending.
1322
+ * Use this when you want to batch multiple events into a single envelope.
1323
+ *
1324
+ * @param input - Activity completion data
1325
+ * @returns A fully-formed ActivityCompletedEvent ready to send
45
1326
  *
46
1327
  * @example
47
1328
  * ```typescript
48
- * // Timeback Profile - Time Spent
49
- * await client.events.sendTimeSpent(
50
- * 'https://myapp.example.com/sensors/main',
51
- * {
52
- * actor: { id: '...', type: 'TimebackUser', email: 'student@example.edu' },
53
- * object: { id: '...', type: 'TimebackActivityContext', subject: 'Reading', app: { name: 'My App' } },
54
- * metrics: [
55
- * { type: 'active', value: 1800 }, // 30 minutes
56
- * { type: 'inactive', value: 300 }, // 5 minutes
57
- * ],
58
- * },
59
- * )
1329
+ * import { createActivityEvent, createTimeSpentEvent } from '@timeback/caliper'
1330
+ *
1331
+ * const activityEvent = createActivityEvent({
1332
+ * actor: { id: '...', type: 'TimebackUser', email: 'student@example.edu' },
1333
+ * object: { id: '...', type: 'TimebackActivityContext', subject: 'Math', app: { name: 'My App' } },
1334
+ * metrics: [
1335
+ * { type: 'totalQuestions', value: 10 },
1336
+ * { type: 'correctQuestions', value: 8 },
1337
+ * ],
1338
+ * })
1339
+ *
1340
+ * const timeSpentEvent = createTimeSpentEvent({
1341
+ * actor: { id: '...', type: 'TimebackUser', email: 'student@example.edu' },
1342
+ * object: { id: '...', type: 'TimebackActivityContext', subject: 'Math', app: { name: 'My App' } },
1343
+ * metrics: [{ type: 'active', value: 1800 }],
1344
+ * })
1345
+ *
1346
+ * // Send both in one envelope
1347
+ * await client.events.send(sensor, [activityEvent, timeSpentEvent])
60
1348
  * ```
1349
+ */
1350
+ declare function createActivityEvent(input: ActivityCompletedInput): ActivityCompletedEvent;
1351
+ /**
1352
+ * Create a TimeSpentEvent from input.
1353
+ *
1354
+ * Pure factory function - creates the event object without sending.
1355
+ * Use this when you want to batch multiple events into a single envelope.
1356
+ *
1357
+ * @param input - Time spent data
1358
+ * @returns A fully-formed TimeSpentEvent ready to send
61
1359
  *
62
1360
  * @example
63
1361
  * ```typescript
64
- * // Generic Caliper Events
65
- * // For non-Timeback Caliper events, use the generic method
66
- * await client.events.send('https://sensor.url', [genericCaliperEvent])
1362
+ * import { createTimeSpentEvent } from '@timeback/caliper'
1363
+ *
1364
+ * const event = createTimeSpentEvent({
1365
+ * actor: { id: '...', type: 'TimebackUser', email: 'student@example.edu' },
1366
+ * object: { id: '...', type: 'TimebackActivityContext', subject: 'Reading', app: { name: 'My App' } },
1367
+ * metrics: [
1368
+ * { type: 'active', value: 1800 },
1369
+ * { type: 'inactive', value: 300 },
1370
+ * ],
1371
+ * })
1372
+ *
1373
+ * await client.events.send(sensor, [event])
67
1374
  * ```
68
1375
  */
69
- export { CaliperClient } from './client';
70
- export { createCaliperClient } from './factory';
71
- export type { CaliperClientInstance } from './client';
72
- export type { CaliperClientConfig, Environment, EnvAuth, ExplicitAuth } from './types/client';
73
- export type { AuthCheckResult } from '@timeback/internal-client-infra';
74
- export { createActivityEvent, createTimeSpentEvent } from './lib/event-factories';
75
- export type { TimebackUser, TimebackUserRole, TimebackActivityContext, TimebackSubject, TimebackApp, TimebackCourse, TimebackActivity, TimebackActivityMetric, TimebackActivityMetricsCollection, ActivityMetricType, TimeSpentMetric, TimebackTimeSpentMetricsCollection, TimeSpentMetricType, ActivityCompletedEvent, TimeSpentEvent, TimebackEvent, } from '@timeback/types/protocols/caliper';
76
- export type { ActivityCompletedInput, TimeSpentInput, CaliperListEventsParams as ListEventsParams, } from '@timeback/types/zod';
77
- export { CALIPER_DATA_VERSION } from './constants';
78
- export type { CaliperEnvelope, CaliperEvent, CaliperProfile, JobStatus, SendEventsResult, StoredEvent, ValidationResult, } from '@timeback/types/protocols/caliper';
79
- export { Transport } from './lib';
80
- //# sourceMappingURL=index.d.ts.map
1376
+ declare function createTimeSpentEvent(input: TimeSpentInput): TimeSpentEvent;
1377
+
1378
+ /**
1379
+ * Transport Layer
1380
+ *
1381
+ * HTTP transport for Caliper API communication.
1382
+ */
1383
+
1384
+ /**
1385
+ * HTTP transport layer for Caliper API communication.
1386
+ *
1387
+ * Extends BaseTransport with Caliper-specific path configuration.
1388
+ * Uses body-based pagination (events array + pagination metadata).
1389
+ */
1390
+ declare class Transport extends BaseTransport {
1391
+ /** API path profiles for Caliper operations */
1392
+ readonly paths: CaliperPaths;
1393
+ constructor(config: CaliperTransportConfig);
1394
+ /**
1395
+ * Make a paginated request using body-based pagination.
1396
+ *
1397
+ * Caliper APIs return pagination metadata in the response body:
1398
+ * - `events`: Array of items
1399
+ * - `pagination`: { total, totalPages, currentPage, limit }
1400
+ *
1401
+ * @param path - API endpoint path
1402
+ * @param options - Request options
1403
+ * @returns Normalized paginated response with hasMore and total
1404
+ */
1405
+ requestPaginated<T>(path: string, options?: RequestOptions): Promise<PaginatedResponse<T>>;
1406
+ }
1407
+
1408
+ export { ActivityCompletedInput, CALIPER_DATA_VERSION, CaliperClient, CaliperListEventsParams as ListEventsParams, TimeSpentInput, Transport, createActivityEvent, createCaliperClient, createTimeSpentEvent };
1409
+ export type { ActivityCompletedEvent, ActivityMetricType, CaliperClientConfig, CaliperClientInstance, CaliperEnvelope, CaliperEvent, CaliperProfile, JobStatus, SendEventsResult, StoredEvent, TimeSpentEvent, TimeSpentMetric, TimeSpentMetricType, TimebackActivity, TimebackActivityContext, TimebackActivityMetric, TimebackActivityMetricsCollection, TimebackApp, TimebackCourse, TimebackEvent, TimebackSubject, TimebackTimeSpentMetricsCollection, TimebackUser, TimebackUserRole, ValidationResult };