@timeback/sdk 0.1.4 → 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.
Files changed (71) hide show
  1. package/README.md +46 -23
  2. package/dist/client/adapters/react/index.d.ts +1 -2
  3. package/dist/client/adapters/react/index.d.ts.map +1 -1
  4. package/dist/client/adapters/react/index.js +30 -33
  5. package/dist/client/adapters/react/provider.d.ts +1 -2
  6. package/dist/client/adapters/react/provider.d.ts.map +1 -1
  7. package/dist/client/adapters/solid/context.d.ts +1 -2
  8. package/dist/client/adapters/solid/context.d.ts.map +1 -1
  9. package/dist/client/adapters/solid/context.tsx +1 -2
  10. package/dist/client/adapters/solid/index.d.ts +1 -2
  11. package/dist/client/adapters/solid/index.d.ts.map +1 -1
  12. package/dist/client/adapters/solid/index.ts +1 -2
  13. package/dist/client/adapters/svelte/index.d.ts +1 -2
  14. package/dist/client/adapters/svelte/index.d.ts.map +1 -1
  15. package/dist/client/adapters/svelte/index.ts +1 -2
  16. package/dist/client/adapters/svelte/stores.d.ts +1 -2
  17. package/dist/client/adapters/svelte/stores.d.ts.map +1 -1
  18. package/dist/client/adapters/svelte/stores.ts +1 -2
  19. package/dist/client/adapters/vue/index.d.ts +1 -2
  20. package/dist/client/adapters/vue/index.d.ts.map +1 -1
  21. package/dist/client/adapters/vue/index.ts +1 -2
  22. package/dist/client/adapters/vue/provider.d.ts +1 -2
  23. package/dist/client/adapters/vue/provider.d.ts.map +1 -1
  24. package/dist/client/adapters/vue/provider.ts +1 -2
  25. package/dist/client/index.d.ts +1 -1
  26. package/dist/client/index.d.ts.map +1 -1
  27. package/dist/client/lib/activity/activity.class.d.ts +21 -21
  28. package/dist/client/lib/activity/activity.class.d.ts.map +1 -1
  29. package/dist/client/lib/activity/index.d.ts +0 -1
  30. package/dist/client/lib/activity/index.d.ts.map +1 -1
  31. package/dist/client/namespaces/activity.d.ts +13 -8
  32. package/dist/client/namespaces/activity.d.ts.map +1 -1
  33. package/dist/client.d.ts +4 -4
  34. package/dist/client.d.ts.map +1 -1
  35. package/dist/client.js +30 -34
  36. package/dist/edge.d.ts +1 -1
  37. package/dist/index.d.ts +1 -5
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +25888 -6188
  40. package/dist/server/adapters/express.js +19592 -927
  41. package/dist/server/adapters/nuxt.js +19596 -931
  42. package/dist/server/adapters/solid-start.js +19594 -929
  43. package/dist/server/adapters/tanstack-start.js +19592 -927
  44. package/dist/server/handlers/activity.d.ts +4 -7
  45. package/dist/server/handlers/activity.d.ts.map +1 -1
  46. package/dist/server/handlers/user.d.ts.map +1 -1
  47. package/dist/server/lib/build-activity-events.d.ts +29 -1
  48. package/dist/server/lib/build-activity-events.d.ts.map +1 -1
  49. package/dist/server/lib/index.d.ts +2 -4
  50. package/dist/server/lib/index.d.ts.map +1 -1
  51. package/dist/server/lib/resolve.d.ts +112 -0
  52. package/dist/server/lib/resolve.d.ts.map +1 -0
  53. package/dist/server/timeback-identity.d.ts +2 -2
  54. package/dist/server/timeback.d.ts +2 -2
  55. package/dist/server/timeback.d.ts.map +1 -1
  56. package/dist/server/types.d.ts +152 -27
  57. package/dist/server/types.d.ts.map +1 -1
  58. package/dist/shared/types.d.ts +118 -9
  59. package/dist/shared/types.d.ts.map +1 -1
  60. package/package.json +4 -8
  61. package/dist/client/lib/activity/activity.d.ts +0 -16
  62. package/dist/client/lib/activity/activity.d.ts.map +0 -1
  63. package/dist/config.d.ts +0 -20
  64. package/dist/config.d.ts.map +0 -1
  65. package/dist/config.js +0 -0
  66. package/dist/server/lib/resolve-activity-course.d.ts +0 -22
  67. package/dist/server/lib/resolve-activity-course.d.ts.map +0 -1
  68. package/dist/server/lib/resolve-timeback-id.d.ts +0 -28
  69. package/dist/server/lib/resolve-timeback-id.d.ts.map +0 -1
  70. package/dist/server/lib/resolve-timeback-user.d.ts +0 -42
  71. package/dist/server/lib/resolve-timeback-user.d.ts.map +0 -1
package/README.md CHANGED
@@ -40,7 +40,7 @@ bun add timeback
40
40
 
41
41
  ## Server Adapters
42
42
 
43
- All server adapters use the same core configuration:
43
+ All server adapters use the same core configuration and require a `timeback.config.json` file:
44
44
 
45
45
  ```typescript
46
46
  // lib/timeback.ts
@@ -76,7 +76,6 @@ export const timeback = await createTimeback({
76
76
  ```typescript
77
77
  // app/api/timeback/[...timeback]/route.ts
78
78
  import { toNextjsHandler } from '@timeback/sdk/nextjs'
79
-
80
79
  import { timeback } from '@/lib/timeback'
81
80
 
82
81
  export const { GET, POST } = toNextjsHandler(timeback)
@@ -105,6 +104,7 @@ export default defineEventHandler(async event => {
105
104
  // src/hooks.server.ts
106
105
  import { building } from '$app/environment'
107
106
  import { timeback } from '$lib/timeback'
107
+
108
108
  import { svelteKitHandler } from '@timeback/sdk/svelte-kit'
109
109
 
110
110
  import type { Handle } from '@sveltejs/kit'
@@ -125,6 +125,7 @@ export const handle: Handle = ({ event, resolve }) => {
125
125
  // src/middleware.ts
126
126
  import { createMiddleware } from '@solidjs/start/middleware'
127
127
  import { timeback } from '~/lib/timeback'
128
+
128
129
  import { solidStartHandler } from '@timeback/sdk/solid-start'
129
130
 
130
131
  export default createMiddleware({
@@ -145,8 +146,8 @@ export default createMiddleware({
145
146
  ```typescript
146
147
  // src/routes/api/timeback/$.ts
147
148
  import { createFileRoute } from '@tanstack/react-router'
148
- import { toTanStackStartHandler } from '@timeback/sdk/tanstack-start'
149
149
 
150
+ import { toTanStackStartHandler } from '@timeback/sdk/tanstack-start'
150
151
  import { timeback } from '@/lib/timeback'
151
152
 
152
153
  const handlers = toTanStackStartHandler(timeback)
@@ -161,6 +162,7 @@ export const Route = createFileRoute('/api/timeback/$')({
161
162
  ```typescript
162
163
  // server.ts
163
164
  import express from 'express'
165
+
164
166
  import { toExpressMiddleware } from '@timeback/sdk/express'
165
167
 
166
168
  import { timeback } from './lib/timeback'
@@ -188,6 +190,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
188
190
  ```tsx
189
191
  // components/ActivityTracker.tsx
190
192
  import { useEffect } from 'react'
193
+
191
194
  import { SignInButton, useTimeback } from '@timeback/sdk/react'
192
195
 
193
196
  function MyComponent() {
@@ -227,9 +230,10 @@ import { TimebackProvider } from '@timeback/sdk/vue'
227
230
  ```vue
228
231
  <!-- components/ActivityTracker.vue -->
229
232
  <script setup>
230
- import { SignInButton, useTimeback } from '@timeback/sdk/vue'
231
233
  import { onMounted, onUnmounted } from 'vue'
232
234
 
235
+ import { SignInButton, useTimeback } from '@timeback/sdk/vue'
236
+
233
237
  const timeback = useTimeback()
234
238
  let activity
235
239
 
@@ -306,6 +310,7 @@ export default function App() {
306
310
  ```tsx
307
311
  // components/ActivityTracker.tsx
308
312
  import { onCleanup, onMount } from 'solid-js'
313
+
309
314
  import { SignInButton, useTimeback } from '@timeback/sdk/solid'
310
315
 
311
316
  function MyComponent() {
@@ -401,21 +406,21 @@ For apps with existing auth (Clerk, Auth0, Supabase, etc.):
401
406
  ```typescript
402
407
  identity: {
403
408
  mode: 'custom',
404
- getUser: async (req) => {
409
+ getEmail: async (req) => {
405
410
  const session = await getSession(req)
406
- if (!session) return undefined
407
- // Return user with timebackId as the id
408
- return { id: session.timebackId, email: session.email, name: session.name }
411
+ return session?.email
409
412
  },
410
413
  }
411
414
  ```
412
415
 
416
+ The SDK resolves the Timeback user by email. You only need to provide the authenticated user's email address.
417
+
413
418
  ## Identity-Only Integration
414
419
 
415
420
  If you only need Timeback SSO authentication without activity tracking or Timeback API integration, use `createTimebackIdentity()`. This is a lightweight alternative that:
416
421
 
417
422
  - Does not require Timeback API credentials
418
- - Does not require `timeback.config.ts`
423
+ - Does not require `timeback.config.json`
419
424
  - Only exposes identity routes (sign-in, callback, sign-out)
420
425
  - Returns raw OIDC user info (no Timeback profile enrichment)
421
426
 
@@ -424,8 +429,8 @@ If you only need Timeback SSO authentication without activity tracking or Timeba
424
429
  ### Cloudflare Workers / workerd compatibility
425
430
 
426
431
  `createTimebackIdentity()` is runtime-agnostic, but the main `timeback` entrypoint also includes
427
- Node-oriented functionality (notably config loading via `jiti`). Some edge runtimes
428
- (Cloudflare Workers / workerd) do not support the Node modules that `jiti` depends on.
432
+ Node-oriented functionality (notably config loading via `c12`). Some edge runtimes
433
+ (Cloudflare Workers / workerd) do not support the Node modules that `c12` depends on.
429
434
 
430
435
  If you're deploying identity-only SSO on Workers/workerd, import from the worker-safe entrypoint:
431
436
 
@@ -469,7 +474,6 @@ export const timeback = createTimebackIdentity({
469
474
  ```typescript
470
475
  // app/api/timeback/[...timeback]/route.ts
471
476
  import { toNextjsHandler } from '@timeback/sdk/nextjs'
472
-
473
477
  import { timeback } from '@/lib/timeback'
474
478
 
475
479
  export const { GET, POST } = toNextjsHandler(timeback)
@@ -480,6 +484,7 @@ export const { GET, POST } = toNextjsHandler(timeback)
480
484
  ```typescript
481
485
  // server.ts
482
486
  import express from 'express'
487
+
483
488
  import { toExpressMiddleware } from '@timeback/sdk/express'
484
489
 
485
490
  import { timeback } from './lib/timeback'
@@ -529,21 +534,39 @@ await activity.end({
529
534
  totalQuestions: 10,
530
535
  correctQuestions: 8,
531
536
  xpEarned: 80,
532
- masteredUnits: 1,
537
+ masteredUnits: 1, // optional (default: omitted)
538
+ attemptNumber: 2, // optional (default: omitted)
539
+ pctCompleteApp: 67, // optional (default: omitted; clamped to 0–100 by the SDK server handler if present)
533
540
  })
534
541
  ```
535
542
 
536
543
  The SDK automatically sends activity data to your server, which forwards it to the Timeback API.
537
544
 
538
- **Note:** Activity ingestion requires **exactly one** Caliper sensor URL in `timeback.config.ts`:
539
-
540
- ```typescript
541
- export default {
542
- name: 'My App',
543
- courses: [
544
- /* ... */
545
- ],
546
- sensors: ['https://my-app.example.com/sensors/main'],
545
+ **Note:** Activity ingestion requires an **effective Caliper sensor URL per course** in `timeback.config.json`.
546
+
547
+ Sensor precedence (highest → lowest):
548
+
549
+ - per-course env override: `course.overrides[env].sensor`
550
+ - per-course base override: `course.sensor`
551
+ - top-level default: `config.sensor`
552
+
553
+ ```json
554
+ {
555
+ "$schema": "https://timeback.dev/schema.json",
556
+ "name": "My App",
557
+ "sensor": "https://my-app.example.com/sensors/default",
558
+ "courses": [
559
+ {
560
+ "subject": "Math",
561
+ "grade": 3,
562
+ "courseCode": "MATH-3",
563
+ "sensor": "https://my-app.example.com/sensors/math",
564
+ "overrides": {
565
+ "staging": { "sensor": "https://staging.my-app.example.com/sensors/math" },
566
+ "production": { "sensor": "https://my-app.example.com/sensors/math" }
567
+ }
568
+ }
569
+ ]
547
570
  }
548
571
  ```
549
572
 
@@ -575,7 +598,7 @@ export const timeback = await createTimeback({
575
598
  clientId: process.env.TIMEBACK_API_CLIENT_ID!,
576
599
  clientSecret: process.env.TIMEBACK_API_CLIENT_SECRET!,
577
600
  },
578
- identity: { mode: 'custom', getUser: () => getSession() },
601
+ identity: { mode: 'custom', getEmail: () => getSession()?.email },
579
602
  })
580
603
 
581
604
  // Access the API client via timeback.api
@@ -25,12 +25,11 @@
25
25
  * }
26
26
  *
27
27
  * const handleStartActivity = () => {
28
- * const activity = timeback?.activity.new({
28
+ * const activity = timeback?.activity.start({
29
29
  * id: 'lesson-1',
30
30
  * name: 'Intro',
31
31
  * course: { subject: 'Math', grade: 3 },
32
32
  * })
33
- * activity?.start()
34
33
  * }
35
34
  *
36
35
  * return <SignInButton />
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAG5D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAG7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAGvD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAG5D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAG7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAGvD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA"}
@@ -35,24 +35,16 @@ class Activity {
35
35
  constructor(params, sendActivity) {
36
36
  this.params = params;
37
37
  this.sendActivity = sendActivity;
38
- }
39
- get isStarted() {
40
- return this._startedAt !== undefined;
38
+ this._startedAt = new Date;
41
39
  }
42
40
  get startedAt() {
43
41
  return this._startedAt;
44
42
  }
45
- start() {
46
- if (this._startedAt)
47
- return this;
48
- this._startedAt = new Date;
49
- return this;
50
- }
51
43
  get isPaused() {
52
44
  return this._isPaused;
53
45
  }
54
46
  get elapsedMs() {
55
- if (!this._startedAt || this._ended) {
47
+ if (this._ended) {
56
48
  return 0;
57
49
  }
58
50
  const now = new Date;
@@ -62,8 +54,30 @@ class Activity {
62
54
  }
63
55
  return Math.max(0, elapsed);
64
56
  }
57
+ _buildPayload(data) {
58
+ const now = new Date;
59
+ const pausedMs = this._totalPausedMs + (this._isPaused && this._pausedAt ? now.getTime() - this._pausedAt.getTime() : 0);
60
+ const elapsedMs = now.getTime() - this._startedAt.getTime() - pausedMs;
61
+ return {
62
+ id: this.params.id,
63
+ name: this.params.name,
64
+ course: this.params.course,
65
+ startedAt: this._startedAt.toISOString(),
66
+ endedAt: now.toISOString(),
67
+ elapsedMs: Math.max(0, elapsedMs),
68
+ pausedMs,
69
+ metrics: {
70
+ totalQuestions: data.totalQuestions,
71
+ correctQuestions: data.correctQuestions,
72
+ ...data.xpEarned === undefined ? {} : { xpEarned: data.xpEarned },
73
+ ...data.masteredUnits === undefined ? {} : { masteredUnits: data.masteredUnits }
74
+ },
75
+ ...data.attemptNumber === undefined ? {} : { attemptNumber: data.attemptNumber },
76
+ ...data.pctCompleteApp === undefined ? {} : { pctCompleteApp: data.pctCompleteApp }
77
+ };
78
+ }
65
79
  pause() {
66
- if (!this._startedAt || this._isPaused || this._ended)
80
+ if (this._isPaused || this._ended)
67
81
  return;
68
82
  this._isPaused = true;
69
83
  this._pausedAt = new Date;
@@ -75,43 +89,26 @@ class Activity {
75
89
  this._isPaused = false;
76
90
  this._pausedAt = undefined;
77
91
  }
78
- async end(metrics) {
79
- if (!this._startedAt) {
80
- throw new Error("Cannot end activity that was never started");
81
- }
92
+ async end(data) {
82
93
  if (this._ended)
83
94
  return;
84
95
  this._ended = true;
85
96
  if (this._isPaused && this._pausedAt) {
86
97
  this._totalPausedMs += new Date().getTime() - this._pausedAt.getTime();
98
+ this._isPaused = false;
99
+ this._pausedAt = undefined;
87
100
  }
88
- const endedAt = new Date;
89
- const elapsedMs = endedAt.getTime() - this._startedAt.getTime() - this._totalPausedMs;
90
- const payload = {
91
- id: this.params.id,
92
- name: this.params.name,
93
- course: this.params.course,
94
- startedAt: this._startedAt.toISOString(),
95
- endedAt: endedAt.toISOString(),
96
- elapsedMs: Math.max(0, elapsedMs),
97
- pausedMs: this._totalPausedMs,
98
- metrics
99
- };
101
+ const payload = this._buildPayload(data);
100
102
  await this.sendActivity(payload);
101
103
  }
102
104
  }
103
-
104
- // src/client/lib/activity/activity.ts
105
- function createActivity(params, sendActivity) {
106
- return new Activity(params, sendActivity);
107
- }
108
105
  // src/client/namespaces/activity.ts
109
106
  class ActivityManager {
110
107
  sendActivity;
111
108
  constructor(sendActivity) {
112
109
  this.sendActivity = sendActivity;
113
110
  }
114
- new(params) {
111
+ start(params) {
115
112
  return new Activity(params, this.sendActivity);
116
113
  }
117
114
  }
@@ -61,12 +61,11 @@ export declare function TimebackProvider({ client: providedClient, children }: T
61
61
  * }
62
62
  *
63
63
  * const handleStartActivity = () => {
64
- * const activity = timeback.activity.new({
64
+ * const activity = timeback.activity.start({
65
65
  * id: 'lesson-1',
66
66
  * name: 'Intro',
67
67
  * course: { subject: 'Math', grade: 3 },
68
68
  * })
69
- * activity.start()
70
69
  * }
71
70
  *
72
71
  * return <button onClick={handleSignIn}>Sign In</button>
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/react/provider.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAO5D;;GAEG;AACH,UAAU,qBAAqB;IAC9B,wFAAwF;IACxF,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,uBAAuB;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB;AAiBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,EAChC,MAAM,EAAE,cAAc,EACtB,QAAQ,EACR,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAU5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,WAAW,IAAI,cAAc,GAAG,SAAS,CAExD"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/react/provider.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAO5D;;GAEG;AACH,UAAU,qBAAqB;IAC9B,wFAAwF;IACxF,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,uBAAuB;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB;AAiBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,EAChC,MAAM,EAAE,cAAc,EACtB,QAAQ,EACR,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAU5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,WAAW,IAAI,cAAc,GAAG,SAAS,CAExD"}
@@ -57,12 +57,11 @@ export declare function TimebackProvider(props: TimebackProviderProps): JSX.Elem
57
57
  * }
58
58
  *
59
59
  * const handleStartActivity = () => {
60
- * const activity = timeback?.activity.new({
60
+ * const activity = timeback?.activity.start({
61
61
  * id: 'lesson-1',
62
62
  * name: 'Intro',
63
63
  * course: { subject: 'Math', grade: 3 }
64
64
  * })
65
- * activity?.start()
66
65
  * }
67
66
  *
68
67
  * return <button onClick={handleSignIn}>Sign In</button>
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/solid/context.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAOnC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,sCAAsC;IACtC,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,yBAAyB;IACzB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,GAAG,CAAC,OAAO,CAI1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,WAAW,IAAI,cAAc,GAAG,SAAS,CAExD"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/solid/context.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAOnC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,sCAAsC;IACtC,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,yBAAyB;IACzB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,GAAG,CAAC,OAAO,CAI1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,WAAW,IAAI,cAAc,GAAG,SAAS,CAExD"}
@@ -74,12 +74,11 @@ export function TimebackProvider(props: TimebackProviderProps): JSX.Element {
74
74
  * }
75
75
  *
76
76
  * const handleStartActivity = () => {
77
- * const activity = timeback?.activity.new({
77
+ * const activity = timeback?.activity.start({
78
78
  * id: 'lesson-1',
79
79
  * name: 'Intro',
80
80
  * course: { subject: 'Math', grade: 3 }
81
81
  * })
82
- * activity?.start()
83
82
  * }
84
83
  *
85
84
  * return <button onClick={handleSignIn}>Sign In</button>
@@ -25,12 +25,11 @@
25
25
  * }
26
26
  *
27
27
  * const handleStartActivity = () => {
28
- * const activity = timeback?.activity.new({
28
+ * const activity = timeback?.activity.start({
29
29
  * id: 'lesson-1',
30
30
  * name: 'Intro',
31
31
  * course: { subject: 'Math', grade: 3 },
32
32
  * })
33
- * activity?.start()
34
33
  * }
35
34
  *
36
35
  * return <SignInButton />
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/solid/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC7E,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG7F,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACzD,YAAY,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAGtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/solid/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC7E,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG7F,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACzD,YAAY,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAGtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA"}
@@ -25,12 +25,11 @@
25
25
  * }
26
26
  *
27
27
  * const handleStartActivity = () => {
28
- * const activity = timeback?.activity.new({
28
+ * const activity = timeback?.activity.start({
29
29
  * id: 'lesson-1',
30
30
  * name: 'Intro',
31
31
  * course: { subject: 'Math', grade: 3 },
32
32
  * })
33
- * activity?.start()
34
33
  * }
35
34
  *
36
35
  * return <SignInButton />
@@ -17,12 +17,11 @@
17
17
  * }
18
18
  *
19
19
  * function handleStartActivity() {
20
- * const activity = $timeback?.activity.new({
20
+ * const activity = $timeback?.activity.start({
21
21
  * id: 'lesson-1',
22
22
  * name: 'Intro',
23
23
  * course: { subject: 'Math', grade: 3 },
24
24
  * })
25
- * activity?.start()
26
25
  * }
27
26
  * </script>
28
27
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC7E,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG7F,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGjD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAC/D,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC7E,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG7F,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGjD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAC/D,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA"}
@@ -17,12 +17,11 @@
17
17
  * }
18
18
  *
19
19
  * function handleStartActivity() {
20
- * const activity = $timeback?.activity.new({
20
+ * const activity = $timeback?.activity.start({
21
21
  * id: 'lesson-1',
22
22
  * name: 'Intro',
23
23
  * course: { subject: 'Math', grade: 3 },
24
24
  * })
25
- * activity?.start()
26
25
  * }
27
26
  * </script>
28
27
  *
@@ -51,12 +51,11 @@ export declare function initTimeback(client?: TimebackClient): void;
51
51
  * }
52
52
  *
53
53
  * function handleStartActivity() {
54
- * const activity = $timeback?.activity.new({
54
+ * const activity = $timeback?.activity.start({
55
55
  * id: 'lesson-1',
56
56
  * name: 'Intro',
57
57
  * course: { subject: 'Math', grade: 3 },
58
58
  * })
59
- * activity?.start()
60
59
  * }
61
60
  * </script>
62
61
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/svelte/stores.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD;;;;GAIG;AACH,UAAU,QAAQ,CAAC,CAAC;IACnB,SAAS,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;CAClD;AAqDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAQ1D;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,cAAc,GAAG,SAAS,CAAe,CAAA"}
1
+ {"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/svelte/stores.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD;;;;GAIG;AACH,UAAU,QAAQ,CAAC,CAAC;IACnB,SAAS,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;CAClD;AAqDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAQ1D;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,cAAc,GAAG,SAAS,CAAe,CAAA"}
@@ -130,12 +130,11 @@ if (isBrowser()) {
130
130
  * }
131
131
  *
132
132
  * function handleStartActivity() {
133
- * const activity = $timeback?.activity.new({
133
+ * const activity = $timeback?.activity.start({
134
134
  * id: 'lesson-1',
135
135
  * name: 'Intro',
136
136
  * course: { subject: 'Math', grade: 3 },
137
137
  * })
138
- * activity?.start()
139
138
  * }
140
139
  * </script>
141
140
  * ```
@@ -19,12 +19,11 @@
19
19
  * }
20
20
  *
21
21
  * function handleStartActivity() {
22
- * const activity = timeback.value?.activity.new({
22
+ * const activity = timeback.value?.activity.start({
23
23
  * id: 'lesson-1',
24
24
  * name: 'Intro',
25
25
  * course: { subject: 'Math', grade: 3 }
26
26
  * })
27
- * activity?.start()
28
27
  * }
29
28
  * </script>
30
29
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/vue/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC7E,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG7F,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG1D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/vue/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC7E,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG7F,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG1D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA"}
@@ -19,12 +19,11 @@
19
19
  * }
20
20
  *
21
21
  * function handleStartActivity() {
22
- * const activity = timeback.value?.activity.new({
22
+ * const activity = timeback.value?.activity.start({
23
23
  * id: 'lesson-1',
24
24
  * name: 'Intro',
25
25
  * course: { subject: 'Math', grade: 3 }
26
26
  * })
27
- * activity?.start()
28
27
  * }
29
28
  * </script>
30
29
  *
@@ -76,12 +76,11 @@ export declare const TimebackProvider: import("@vue/runtime-core").DefineCompone
76
76
  * }
77
77
  *
78
78
  * function handleStartActivity() {
79
- * const activity = timeback.value?.activity.new({
79
+ * const activity = timeback.value?.activity.start({
80
80
  * id: 'lesson-1',
81
81
  * name: 'Intro',
82
82
  * course: { subject: 'Math', grade: 3 }
83
83
  * })
84
- * activity?.start()
85
84
  * }
86
85
  * </script>
87
86
  *
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/vue/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAGrD,OAAO,KAAK,EAAgB,QAAQ,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAqC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,gBAAgB;IAG3B,wFAAwF;;;;;;;;IAAxF,wFAAwF;;;;;;;0FAoBxF,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,WAAW,IAAI,UAAU,CAAC,cAAc,GAAG,SAAS,CAAC,CAQpE"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/vue/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAGrD,OAAO,KAAK,EAAgB,QAAQ,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAqC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,gBAAgB;IAG3B,wFAAwF;;;;;;;;IAAxF,wFAAwF;;;;;;;0FAoBxF,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,WAAW,IAAI,UAAU,CAAC,cAAc,GAAG,SAAS,CAAC,CAQpE"}
@@ -122,12 +122,11 @@ export const TimebackProvider = defineComponent({
122
122
  * }
123
123
  *
124
124
  * function handleStartActivity() {
125
- * const activity = timeback.value?.activity.new({
125
+ * const activity = timeback.value?.activity.start({
126
126
  * id: 'lesson-1',
127
127
  * name: 'Intro',
128
128
  * course: { subject: 'Math', grade: 3 }
129
129
  * })
130
- * activity?.start()
131
130
  * }
132
131
  * </script>
133
132
  *
@@ -5,5 +5,5 @@
5
5
  */
6
6
  export { createClient } from './timeback-client';
7
7
  export { TimebackClient } from './timeback-client.class';
8
- export { createActivity, Activity } from './lib/activity';
8
+ export { Activity } from './lib/activity';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAGxD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAGxD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA"}
@@ -6,42 +6,33 @@
6
6
  import type { ActivityEndPayload, ActivityMetrics, ActivityParams } from '../../../shared/types';
7
7
  /**
8
8
  * Activity tracker that tracks time spent on an activity.
9
+ *
10
+ * Activities are started immediately on construction. Use `pause()`, `resume()`,
11
+ * and `end()` to control the activity lifecycle.
9
12
  */
10
13
  export declare class Activity {
11
14
  private readonly params;
12
15
  private readonly sendActivity;
13
- private _startedAt;
16
+ private readonly _startedAt;
14
17
  private _isPaused;
15
18
  private _pausedAt;
16
19
  private _totalPausedMs;
17
20
  private _ended;
18
21
  /**
19
- * Create a new activity tracker.
22
+ * Create and start a new activity tracker.
20
23
  *
21
- * The activity is created but not started. Call `.start()` to begin tracking.
24
+ * The activity timer begins immediately.
22
25
  *
23
26
  * @param params - Activity parameters
24
27
  * @param sendActivity - Function to send activity to server
25
28
  */
26
29
  constructor(params: ActivityParams, sendActivity: (payload: ActivityEndPayload) => Promise<void>);
27
- /**
28
- * Whether the activity has been started.
29
- *
30
- * @returns True if started
31
- */
32
- get isStarted(): boolean;
33
30
  /**
34
31
  * When the activity was started.
35
32
  *
36
- * @returns Start date or undefined if not started
33
+ * @returns Start date
37
34
  */
38
- get startedAt(): Date | undefined;
39
- /**
40
- * Start tracking the activity.
41
- *
42
- * @returns This activity for chaining
43
- */
44
- start(): this;
35
+ get startedAt(): Date;
45
36
  /**
46
37
  * Whether the activity is currently paused.
47
38
  *
@@ -51,9 +42,19 @@ export declare class Activity {
51
42
  /**
52
43
  * Total elapsed time in milliseconds (excluding paused time).
53
44
  *
54
- * @returns Elapsed milliseconds (0 if not started)
45
+ * @returns Elapsed milliseconds (0 if ended)
55
46
  */
56
47
  get elapsedMs(): number;
48
+ /**
49
+ * Build the activity end payload without sending it.
50
+ *
51
+ * Useful for "preview" flows in examples where you want to inspect the payload
52
+ * that would be POSTed to the server without calling `end()`.
53
+ *
54
+ * @param data - Activity completion data (metrics + optional metadata)
55
+ * @returns Activity end payload
56
+ */
57
+ _buildPayload(data: ActivityMetrics & Pick<Partial<ActivityEndPayload>, 'attemptNumber' | 'pctCompleteApp'>): ActivityEndPayload;
57
58
  /**
58
59
  * Pause the activity timer.
59
60
  */
@@ -65,9 +66,8 @@ export declare class Activity {
65
66
  /**
66
67
  * End the activity and send to server.
67
68
  *
68
- * @param metrics - Activity metrics (required)
69
- * @throws Error if activity was never started
69
+ * @param data - Activity completion data (metrics + optional metadata)
70
70
  */
71
- end(metrics: ActivityMetrics): Promise<void>;
71
+ end(data: ActivityMetrics & Pick<Partial<ActivityEndPayload>, 'attemptNumber' | 'pctCompleteApp'>): Promise<void>;
72
72
  }
73
73
  //# sourceMappingURL=activity.class.d.ts.map