timeback 0.0.0-alpha.2 → 0.1.1

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 (113) hide show
  1. package/README.md +378 -7
  2. package/dist/client/adapters/react/SignInButton.d.ts +60 -0
  3. package/dist/client/adapters/react/SignInButton.d.ts.map +1 -0
  4. package/dist/client/adapters/react/index.d.ts +43 -0
  5. package/dist/client/adapters/react/index.d.ts.map +1 -0
  6. package/dist/client/adapters/react/index.js +478 -0
  7. package/dist/client/adapters/react/provider.d.ts +74 -0
  8. package/dist/client/adapters/react/provider.d.ts.map +1 -0
  9. package/dist/client/adapters/solid/SignInButton.d.ts +52 -0
  10. package/dist/client/adapters/solid/SignInButton.d.ts.map +1 -0
  11. package/dist/client/adapters/solid/SignInButton.tsx +321 -0
  12. package/dist/client/adapters/solid/context.d.ts +73 -0
  13. package/dist/client/adapters/solid/context.d.ts.map +1 -0
  14. package/dist/client/adapters/solid/context.tsx +91 -0
  15. package/dist/client/adapters/solid/index.d.ts +42 -0
  16. package/dist/client/adapters/solid/index.d.ts.map +1 -0
  17. package/dist/client/adapters/solid/index.ts +46 -0
  18. package/dist/client/adapters/svelte/SignInButton.svelte +234 -0
  19. package/dist/client/adapters/svelte/SignInButton.svelte.d.ts +24 -0
  20. package/dist/client/adapters/svelte/index.d.ts +33 -0
  21. package/dist/client/adapters/svelte/index.d.ts.map +1 -0
  22. package/dist/client/adapters/svelte/index.ts +38 -0
  23. package/dist/client/adapters/svelte/stores.d.ts +62 -0
  24. package/dist/client/adapters/svelte/stores.d.ts.map +1 -0
  25. package/dist/client/adapters/svelte/stores.ts +139 -0
  26. package/dist/client/adapters/vue/SignInButton.vue +260 -0
  27. package/dist/client/adapters/vue/SignInButton.vue.d.ts +53 -0
  28. package/dist/client/adapters/vue/index.d.ts +43 -0
  29. package/dist/client/adapters/vue/index.d.ts.map +1 -0
  30. package/dist/client/adapters/vue/index.ts +48 -0
  31. package/dist/client/adapters/vue/provider.d.ts +94 -0
  32. package/dist/client/adapters/vue/provider.d.ts.map +1 -0
  33. package/dist/client/adapters/vue/provider.ts +147 -0
  34. package/dist/client/index.d.ts +9 -0
  35. package/dist/client/index.d.ts.map +1 -0
  36. package/dist/client/lib/activity/activity.class.d.ts +73 -0
  37. package/dist/client/lib/activity/activity.class.d.ts.map +1 -0
  38. package/dist/client/lib/activity/activity.d.ts +16 -0
  39. package/dist/client/lib/activity/activity.d.ts.map +1 -0
  40. package/dist/client/lib/activity/index.d.ts +6 -0
  41. package/dist/client/lib/activity/index.d.ts.map +1 -0
  42. package/dist/client/lib/utils.d.ts +20 -0
  43. package/dist/client/lib/utils.d.ts.map +1 -0
  44. package/dist/client/namespaces/activity.d.ts +37 -0
  45. package/dist/client/namespaces/activity.d.ts.map +1 -0
  46. package/dist/client/namespaces/auth.d.ts +33 -0
  47. package/dist/client/namespaces/auth.d.ts.map +1 -0
  48. package/dist/client/namespaces/index.d.ts +7 -0
  49. package/dist/client/namespaces/index.d.ts.map +1 -0
  50. package/dist/client/namespaces/user.d.ts +29 -0
  51. package/dist/client/namespaces/user.d.ts.map +1 -0
  52. package/dist/client/timeback-client.class.d.ts +37 -0
  53. package/dist/client/timeback-client.class.d.ts.map +1 -0
  54. package/dist/client/timeback-client.d.ts +29 -0
  55. package/dist/client/timeback-client.d.ts.map +1 -0
  56. package/dist/client.d.ts +30 -0
  57. package/dist/client.d.ts.map +1 -0
  58. package/dist/client.js +198 -0
  59. package/dist/index.d.ts +27 -14
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +1373 -11
  62. package/dist/server/adapters/express.d.ts +62 -0
  63. package/dist/server/adapters/express.d.ts.map +1 -0
  64. package/dist/server/adapters/express.js +565 -0
  65. package/dist/server/adapters/native.d.ts +45 -0
  66. package/dist/server/adapters/native.d.ts.map +1 -0
  67. package/dist/server/adapters/native.js +509 -0
  68. package/dist/server/adapters/nextjs.d.ts +30 -0
  69. package/dist/server/adapters/nextjs.d.ts.map +1 -0
  70. package/dist/server/adapters/nextjs.js +521 -0
  71. package/dist/server/adapters/nuxt.d.ts +96 -0
  72. package/dist/server/adapters/nuxt.d.ts.map +1 -0
  73. package/dist/server/adapters/nuxt.js +663 -0
  74. package/dist/server/adapters/solid-start.d.ts +61 -0
  75. package/dist/server/adapters/solid-start.d.ts.map +1 -0
  76. package/dist/server/adapters/solid-start.js +551 -0
  77. package/dist/server/adapters/svelte-kit.d.ts +82 -0
  78. package/dist/server/adapters/svelte-kit.d.ts.map +1 -0
  79. package/dist/server/adapters/svelte-kit.js +572 -0
  80. package/dist/server/adapters/tanstack-start.d.ts +40 -0
  81. package/dist/server/adapters/tanstack-start.d.ts.map +1 -0
  82. package/dist/server/adapters/tanstack-start.js +522 -0
  83. package/dist/server/adapters/types.d.ts +280 -0
  84. package/dist/server/adapters/types.d.ts.map +1 -0
  85. package/dist/server/adapters/utils.d.ts +15 -0
  86. package/dist/server/adapters/utils.d.ts.map +1 -0
  87. package/dist/server/handlers/activity.d.ts +28 -0
  88. package/dist/server/handlers/activity.d.ts.map +1 -0
  89. package/dist/server/handlers/identity.d.ts +24 -0
  90. package/dist/server/handlers/identity.d.ts.map +1 -0
  91. package/dist/server/handlers/index.d.ts +9 -0
  92. package/dist/server/handlers/index.d.ts.map +1 -0
  93. package/dist/server/handlers/user.d.ts +30 -0
  94. package/dist/server/handlers/user.d.ts.map +1 -0
  95. package/dist/server/index.d.ts +10 -0
  96. package/dist/server/index.d.ts.map +1 -0
  97. package/dist/server/lib/index.d.ts +9 -0
  98. package/dist/server/lib/index.d.ts.map +1 -0
  99. package/dist/server/lib/logger.d.ts +21 -0
  100. package/dist/server/lib/logger.d.ts.map +1 -0
  101. package/dist/server/lib/oidc.d.ts +76 -0
  102. package/dist/server/lib/oidc.d.ts.map +1 -0
  103. package/dist/server/lib/utils.d.ts +39 -0
  104. package/dist/server/lib/utils.d.ts.map +1 -0
  105. package/dist/server/timeback.d.ts +48 -0
  106. package/dist/server/timeback.d.ts.map +1 -0
  107. package/dist/server/types.d.ts +300 -0
  108. package/dist/server/types.d.ts.map +1 -0
  109. package/dist/shared/constants.d.ts +18 -0
  110. package/dist/shared/constants.d.ts.map +1 -0
  111. package/dist/shared/types.d.ts +100 -0
  112. package/dist/shared/types.d.ts.map +1 -0
  113. package/package.json +104 -28
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Activity Class
3
+ *
4
+ * Client-side activity tracking logic.
5
+ */
6
+ import type { ActivityEndPayload, ActivityMetrics, ActivityParams } from '../../../shared/types';
7
+ /**
8
+ * Activity tracker that tracks time spent on an activity.
9
+ */
10
+ export declare class Activity {
11
+ private readonly params;
12
+ private readonly sendActivity;
13
+ private _startedAt;
14
+ private _isPaused;
15
+ private _pausedAt;
16
+ private _totalPausedMs;
17
+ private _ended;
18
+ /**
19
+ * Create a new activity tracker.
20
+ *
21
+ * The activity is created but not started. Call `.start()` to begin tracking.
22
+ *
23
+ * @param params - Activity parameters
24
+ * @param sendActivity - Function to send activity to server
25
+ */
26
+ 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
+ /**
34
+ * When the activity was started.
35
+ *
36
+ * @returns Start date or undefined if not started
37
+ */
38
+ get startedAt(): Date | undefined;
39
+ /**
40
+ * Start tracking the activity.
41
+ *
42
+ * @returns This activity for chaining
43
+ */
44
+ start(): this;
45
+ /**
46
+ * Whether the activity is currently paused.
47
+ *
48
+ * @returns True if paused
49
+ */
50
+ get isPaused(): boolean;
51
+ /**
52
+ * Total elapsed time in milliseconds (excluding paused time).
53
+ *
54
+ * @returns Elapsed milliseconds (0 if not started)
55
+ */
56
+ get elapsedMs(): number;
57
+ /**
58
+ * Pause the activity timer.
59
+ */
60
+ pause(): void;
61
+ /**
62
+ * Resume the activity timer.
63
+ */
64
+ resume(): void;
65
+ /**
66
+ * End the activity and send to server.
67
+ *
68
+ * @param metrics - Activity metrics (required)
69
+ * @throws Error if activity was never started
70
+ */
71
+ end(metrics: ActivityMetrics): Promise<void>;
72
+ }
73
+ //# sourceMappingURL=activity.class.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.class.d.ts","sourceRoot":"","sources":["../../../../src/client/lib/activity/activity.class.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEhG;;GAEG;AACH,qBAAa,QAAQ;IAgBnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAhB9B,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,MAAM,CAAQ;IAEtB;;;;;;;OAOG;IACH,YACkB,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,EAC1E;IAEJ;;;;OAIG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;;OAIG;IACH,IAAI,SAAS,IAAI,IAAI,GAAG,SAAS,CAEhC;IAED;;;;OAIG;IACH,KAAK,IAAI,IAAI,CAIZ;IAED;;;;OAIG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;OAIG;IACH,IAAI,SAAS,IAAI,MAAM,CAatB;IAED;;OAEG;IACH,KAAK,IAAI,IAAI,CAIZ;IAED;;OAEG;IACH,MAAM,IAAI,IAAI,CAKb;IAED;;;;;OAKG;IACG,GAAG,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BjD;CACD"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Activity Factory
3
+ *
4
+ * Factory function for creating activity trackers.
5
+ */
6
+ import { Activity } from './activity.class';
7
+ import type { ActivityEndPayload, ActivityParams } from '../../../shared/types';
8
+ /**
9
+ * Create an activity tracker.
10
+ *
11
+ * @param params - Activity parameters
12
+ * @param sendActivity - Function to send activity to server
13
+ * @returns Activity handle
14
+ */
15
+ export declare function createActivity(params: ActivityParams, sendActivity: (payload: ActivityEndPayload) => Promise<void>): Activity;
16
+ //# sourceMappingURL=activity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../../src/client/lib/activity/activity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE/E;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,GAC1D,QAAQ,CAEV"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Activity Module
3
+ */
4
+ export { createActivity } from './activity';
5
+ export { Activity } from './activity.class';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/lib/activity/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Client Utilities
3
+ *
4
+ * Internal utility functions for the client SDK.
5
+ */
6
+ /**
7
+ * Check if we're in a browser environment.
8
+ *
9
+ * @returns True if in browser
10
+ */
11
+ export declare function isBrowser(): boolean;
12
+ /**
13
+ * Get the default base URL.
14
+ *
15
+ * Returns undefined during SSR - baseURL is resolved lazily on first API call.
16
+ *
17
+ * @returns The default base URL or undefined during SSR
18
+ */
19
+ export declare function getDefaultBaseURL(): string | undefined;
20
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/client/lib/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAMtD"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Activity Namespace
3
+ *
4
+ * Activity creation and management.
5
+ */
6
+ import { Activity } from '../lib/activity';
7
+ import type { ActivityEndPayload, ActivityParams } from '../../shared/types';
8
+ /**
9
+ * Activity namespace for creating and managing activities.
10
+ */
11
+ export declare class ActivityManager {
12
+ private readonly sendActivity;
13
+ /**
14
+ * Create activity manager.
15
+ *
16
+ * @param sendActivity - Function to send activity to server
17
+ */
18
+ constructor(sendActivity: (payload: ActivityEndPayload) => Promise<void>);
19
+ /**
20
+ * Create a new activity.
21
+ *
22
+ * The activity is created but not started. Call `.start()` to begin tracking.
23
+ *
24
+ * @param params - Activity parameters
25
+ * @returns Activity instance
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const activity = timeback.activity.new({ id: 'lesson-1', name: 'Intro', courseCode: 'MATH-1' })
30
+ * activity.start()
31
+ * // ... user completes lesson ...
32
+ * await activity.end({ totalQuestions: 10, correctQuestions: 8 })
33
+ * ```
34
+ */
35
+ new(params: ActivityParams): Activity;
36
+ }
37
+ //# sourceMappingURL=activity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../src/client/namespaces/activity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAE5E;;GAEG;AACH,qBAAa,eAAe;IAMf,OAAO,CAAC,QAAQ,CAAC,YAAY;IALzC;;;;OAIG;IACH,YAA6B,YAAY,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,EAAI;IAE7F;;;;;;;;;;;;;;;OAeG;IACH,GAAG,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CAEpC;CACD"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Auth Namespace
3
+ *
4
+ * SSO redirect helpers for Timeback client.
5
+ * Note: User session state is managed by your own auth system.
6
+ */
7
+ /**
8
+ * Auth interface.
9
+ */
10
+ interface IAuth {
11
+ /** Sign in via Timeback SSO (redirects to IdP) */
12
+ signIn(): void;
13
+ }
14
+ /**
15
+ * SSO redirect helpers for Timeback client.
16
+ */
17
+ export declare class Auth implements IAuth {
18
+ private readonly getBaseURL;
19
+ /**
20
+ * Create auth instance.
21
+ *
22
+ * @param getBaseURL - Function that returns the base URL for API routes
23
+ */
24
+ constructor(getBaseURL: () => string);
25
+ /**
26
+ * Sign in via Timeback SSO.
27
+ *
28
+ * Redirects the browser to the Timeback SSO login page.
29
+ */
30
+ signIn(): void;
31
+ }
32
+ export {};
33
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/client/namespaces/auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;GAEG;AACH,UAAU,KAAK;IACd,kDAAkD;IAClD,MAAM,IAAI,IAAI,CAAA;CACd;AAED;;GAEG;AACH,qBAAa,IAAK,YAAW,KAAK;IAMrB,OAAO,CAAC,QAAQ,CAAC,UAAU;IALvC;;;;OAIG;IACH,YAA6B,UAAU,EAAE,MAAM,MAAM,EAAI;IAEzD;;;;OAIG;IACH,MAAM,IAAI,IAAI,CAKb;CACD"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Client Namespaces
3
+ */
4
+ export { ActivityManager } from './activity';
5
+ export { Auth } from './auth';
6
+ export { User } from './user';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/namespaces/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * User Namespace
3
+ *
4
+ * User identity and profile data.
5
+ */
6
+ import type { TimebackProfile } from '../../shared/types';
7
+ /**
8
+ * User namespace for profile data.
9
+ */
10
+ export declare class User {
11
+ private readonly getBaseURL;
12
+ /**
13
+ * Create user instance.
14
+ *
15
+ * @param getBaseURL - Function that returns the base URL for API routes
16
+ */
17
+ constructor(getBaseURL: () => string);
18
+ /**
19
+ * Fetch the full user profile from the Timeback API.
20
+ *
21
+ * This makes an API call to get enriched user data including XP, school,
22
+ * enrolled courses, and goals.
23
+ *
24
+ * @returns The user's Timeback profile
25
+ * @throws Error if not authenticated or API call fails
26
+ */
27
+ fetch(): Promise<TimebackProfile>;
28
+ }
29
+ //# sourceMappingURL=user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/client/namespaces/user.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEzD;;GAEG;AACH,qBAAa,IAAI;IAMJ,OAAO,CAAC,QAAQ,CAAC,UAAU;IALvC;;;;OAIG;IACH,YAA6B,UAAU,EAAE,MAAM,MAAM,EAAI;IAEzD;;;;;;;;OAQG;IACG,KAAK,IAAI,OAAO,CAAC,eAAe,CAAC,CAoBtC;CACD"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Timeback Client Class
3
+ *
4
+ * Client-side SDK for activity tracking and identity.
5
+ */
6
+ import { ActivityManager, Auth, User } from './namespaces';
7
+ /**
8
+ * Timeback client configuration.
9
+ */
10
+ interface TimebackClientConfig {
11
+ /** Base URL for Timeback API routes. Defaults to window.location.origin + '/api/timeback' */
12
+ baseURL?: string;
13
+ }
14
+ /**
15
+ * Timeback client for activity tracking and identity.
16
+ */
17
+ export declare class TimebackClient {
18
+ readonly activity: ActivityManager;
19
+ readonly auth: Auth;
20
+ readonly user: User;
21
+ private _baseURL;
22
+ /**
23
+ * Create a new Timeback client.
24
+ *
25
+ * @param config - Client configuration
26
+ */
27
+ constructor(config?: TimebackClientConfig);
28
+ /**
29
+ * Get the base URL, resolving lazily if needed.
30
+ *
31
+ * @returns The base URL
32
+ */
33
+ private get baseURL();
34
+ private sendActivity;
35
+ }
36
+ export {};
37
+ //# sourceMappingURL=timeback-client.class.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeback-client.class.d.ts","sourceRoot":"","sources":["../../src/client/timeback-client.class.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAI1D;;GAEG;AACH,UAAU,oBAAoB;IAC7B,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,qBAAa,cAAc;IAC1B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;IAClC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,OAAO,CAAC,QAAQ,CAAoB;IAEpC;;;;OAIG;IACH,YAAY,MAAM,GAAE,oBAAyB,EAK5C;IAED;;;;OAIG;IACH,OAAO,KAAK,OAAO,GAYlB;YAOa,YAAY;CAiB1B"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Timeback Client Factory
3
+ *
4
+ * Factory function for creating Timeback client instances.
5
+ */
6
+ import { TimebackClient } from './timeback-client.class';
7
+ /**
8
+ * Create a Timeback client instance.
9
+ *
10
+ * @param config - Client configuration (baseURL is optional, defaults to window.location.origin + '/api/timeback')
11
+ * @returns Timeback client
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { createClient } from 'timeback/client'
16
+ *
17
+ * // Zero config - uses window.location.origin + '/api/timeback'
18
+ * const client = createClient()
19
+ *
20
+ * // With explicit URL
21
+ * const client = createClient({
22
+ * baseURL: 'https://myapp.com/api/timeback',
23
+ * })
24
+ * ```
25
+ */
26
+ export declare function createClient(config?: {
27
+ baseURL?: string;
28
+ }): TimebackClient;
29
+ //# sourceMappingURL=timeback-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeback-client.d.ts","sourceRoot":"","sources":["../../src/client/timeback-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAExD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,MAAM,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,cAAc,CAG9E"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Timeback Client
3
+ *
4
+ * Framework-agnostic client exports.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createClient } from 'timeback/client'
9
+ *
10
+ * const client = createClient()
11
+ *
12
+ * // Start tracking
13
+ * const activity = client.startActivity({
14
+ * id: 'lesson-123',
15
+ * name: 'Algebra Basics',
16
+ * courseCode: 'FASTMATH-1',
17
+ * })
18
+ *
19
+ * // Pause/resume
20
+ * activity.pause()
21
+ * activity.resume()
22
+ *
23
+ * // End tracking with metrics
24
+ * await activity.end({ totalQuestions: 10, correctQuestions: 8 })
25
+ * ```
26
+ */
27
+ export { createClient, TimebackClient } from './client/index';
28
+ export { createActivity, Activity } from './client/index';
29
+ export type { TimebackUser, TimebackIdentity, TimebackProfile, ActivityParams, ActivityMetrics, } from './shared/types';
30
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzD,YAAY,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,eAAe,GACf,MAAM,gBAAgB,CAAA"}
package/dist/client.js ADDED
@@ -0,0 +1,198 @@
1
+ // src/shared/constants.ts
2
+ var DEFAULT_BASE_PATH = "/api/timeback";
3
+ var ROUTES = {
4
+ ACTIVITY: "/activity",
5
+ IDENTITY: {
6
+ SIGNIN: "/identity/signin",
7
+ SIGNOUT: "/identity/signout",
8
+ CALLBACK: "/identity/callback"
9
+ },
10
+ USER: {
11
+ ME: "/user/me"
12
+ }
13
+ };
14
+
15
+ // src/client/lib/utils.ts
16
+ function isBrowser() {
17
+ return typeof window !== "undefined";
18
+ }
19
+ function getDefaultBaseURL() {
20
+ if (!isBrowser()) {
21
+ return;
22
+ }
23
+ return `${window.location.origin}${DEFAULT_BASE_PATH}`;
24
+ }
25
+
26
+ // src/client/lib/activity/activity.class.ts
27
+ class Activity {
28
+ params;
29
+ sendActivity;
30
+ _startedAt;
31
+ _isPaused = false;
32
+ _pausedAt;
33
+ _totalPausedMs = 0;
34
+ _ended = false;
35
+ constructor(params, sendActivity) {
36
+ this.params = params;
37
+ this.sendActivity = sendActivity;
38
+ }
39
+ get isStarted() {
40
+ return this._startedAt !== undefined;
41
+ }
42
+ get startedAt() {
43
+ return this._startedAt;
44
+ }
45
+ start() {
46
+ if (this._startedAt)
47
+ return this;
48
+ this._startedAt = new Date;
49
+ return this;
50
+ }
51
+ get isPaused() {
52
+ return this._isPaused;
53
+ }
54
+ get elapsedMs() {
55
+ if (!this._startedAt || this._ended) {
56
+ return 0;
57
+ }
58
+ const now = new Date;
59
+ let elapsed = now.getTime() - this._startedAt.getTime() - this._totalPausedMs;
60
+ if (this._isPaused && this._pausedAt) {
61
+ elapsed -= now.getTime() - this._pausedAt.getTime();
62
+ }
63
+ return Math.max(0, elapsed);
64
+ }
65
+ pause() {
66
+ if (!this._startedAt || this._isPaused || this._ended)
67
+ return;
68
+ this._isPaused = true;
69
+ this._pausedAt = new Date;
70
+ }
71
+ resume() {
72
+ if (!this._isPaused || this._ended || !this._pausedAt)
73
+ return;
74
+ this._totalPausedMs += new Date().getTime() - this._pausedAt.getTime();
75
+ this._isPaused = false;
76
+ this._pausedAt = undefined;
77
+ }
78
+ async end(metrics) {
79
+ if (!this._startedAt) {
80
+ throw new Error("Cannot end activity that was never started");
81
+ }
82
+ if (this._ended)
83
+ return;
84
+ this._ended = true;
85
+ if (this._isPaused && this._pausedAt) {
86
+ this._totalPausedMs += new Date().getTime() - this._pausedAt.getTime();
87
+ }
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
+ courseCode: this.params.courseCode,
94
+ startedAt: this._startedAt.toISOString(),
95
+ endedAt: endedAt.toISOString(),
96
+ elapsedMs: Math.max(0, elapsedMs),
97
+ pausedMs: this._totalPausedMs,
98
+ metrics
99
+ };
100
+ await this.sendActivity(payload);
101
+ }
102
+ }
103
+
104
+ // src/client/lib/activity/activity.ts
105
+ function createActivity(params, sendActivity) {
106
+ return new Activity(params, sendActivity);
107
+ }
108
+ // src/client/namespaces/activity.ts
109
+ class ActivityManager {
110
+ sendActivity;
111
+ constructor(sendActivity) {
112
+ this.sendActivity = sendActivity;
113
+ }
114
+ new(params) {
115
+ return new Activity(params, this.sendActivity);
116
+ }
117
+ }
118
+ // src/client/namespaces/auth.ts
119
+ class Auth {
120
+ getBaseURL;
121
+ constructor(getBaseURL) {
122
+ this.getBaseURL = getBaseURL;
123
+ }
124
+ signIn() {
125
+ if (!isBrowser()) {
126
+ throw new Error("signIn() requires a browser environment");
127
+ }
128
+ window.location.href = `${this.getBaseURL()}${ROUTES.IDENTITY.SIGNIN}`;
129
+ }
130
+ }
131
+ // src/client/namespaces/user.ts
132
+ class User {
133
+ getBaseURL;
134
+ constructor(getBaseURL) {
135
+ this.getBaseURL = getBaseURL;
136
+ }
137
+ async fetch() {
138
+ if (!isBrowser()) {
139
+ throw new Error("user.fetch() requires a browser environment");
140
+ }
141
+ const response = await fetch(`${this.getBaseURL()}${ROUTES.USER.ME}`, {
142
+ method: "GET",
143
+ credentials: "include"
144
+ });
145
+ if (!response.ok) {
146
+ const errorResponse = await response.json().catch(() => ({ error: "Unknown error" }));
147
+ throw new Error(errorResponse.error ?? "Failed to fetch user profile");
148
+ }
149
+ return response.json();
150
+ }
151
+ }
152
+ // src/client/timeback-client.class.ts
153
+ class TimebackClient {
154
+ activity;
155
+ auth;
156
+ user;
157
+ _baseURL;
158
+ constructor(config = {}) {
159
+ this._baseURL = config.baseURL;
160
+ this.activity = new ActivityManager((payload) => this.sendActivity(payload));
161
+ this.auth = new Auth(() => this.baseURL);
162
+ this.user = new User(() => this.baseURL);
163
+ }
164
+ get baseURL() {
165
+ if (!this._baseURL) {
166
+ const resolved = getDefaultBaseURL();
167
+ if (!resolved) {
168
+ throw new Error("Timeback client requires a browser environment for default baseURL. " + "Provide an explicit baseURL for server-side usage.");
169
+ }
170
+ this._baseURL = resolved;
171
+ }
172
+ return this._baseURL;
173
+ }
174
+ async sendActivity(payload) {
175
+ const response = await fetch(`${this.baseURL}${ROUTES.ACTIVITY}`, {
176
+ method: "POST",
177
+ headers: { "Content-Type": "application/json" },
178
+ body: JSON.stringify(payload),
179
+ credentials: "include"
180
+ });
181
+ if (!response.ok) {
182
+ const errorResponse = await response.json().catch(() => ({ error: "Unknown error" }));
183
+ throw new Error(errorResponse.error ?? "Failed to send activity");
184
+ }
185
+ }
186
+ }
187
+
188
+ // src/client/timeback-client.ts
189
+ function createClient(config = {}) {
190
+ const baseURL = config.baseURL ?? getDefaultBaseURL();
191
+ return new TimebackClient({ baseURL });
192
+ }
193
+ export {
194
+ createClient,
195
+ createActivity,
196
+ TimebackClient,
197
+ Activity
198
+ };
package/dist/index.d.ts CHANGED
@@ -1,17 +1,30 @@
1
1
  /**
2
- * A simple identity function that returns the input unchanged.
2
+ * Timeback SDK
3
+ *
4
+ * Server-side exports for the Timeback SDK.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createServer } from 'timeback'
9
+ *
10
+ * export const timeback = await createServer({
11
+ * env: 'production',
12
+ * api: {
13
+ * clientId: process.env.TIMEBACK_API_CLIENT_ID!,
14
+ * clientSecret: process.env.TIMEBACK_API_CLIENT_SECRET!,
15
+ * },
16
+ * identity: {
17
+ * mode: 'custom',
18
+ * getUser: async (req) => ({
19
+ * id: session.userId,
20
+ * email: session.user.email,
21
+ * name: session.user.name,
22
+ * }),
23
+ * },
24
+ * })
25
+ * ```
3
26
  */
4
- export declare function identity<T>(value: T): T;
5
- /**
6
- * A no-op function that does nothing.
7
- */
8
- export declare function noop(): void;
9
- /**
10
- * Returns true. Useful as a placeholder predicate.
11
- */
12
- export declare function yes(): boolean;
13
- /**
14
- * Returns false. Useful as a placeholder predicate.
15
- */
16
- export declare function no(): boolean;
27
+ export { createServer } from './server';
28
+ export type { ApiCredentials, CustomIdentityConfig, Environment, IdentityConfig, SsoIdentityConfig, TimebackConfig, TimebackInstance, BuildStateContext, CallbackSuccessContext, CallbackErrorContext, OIDCTokens, OIDCUserInfo, } from './server';
29
+ export type { TimebackUser, ActivityParams, ActivityMetrics } from './shared/types';
17
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAEvC;AAED;;GAEG;AACH,wBAAgB,IAAI,IAAI,IAAI,CAAG;AAE/B;;GAEG;AACH,wBAAgB,GAAG,IAAI,OAAO,CAE7B;AAED;;GAEG;AACH,wBAAgB,EAAE,IAAI,OAAO,CAE5B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,YAAY,EACX,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAEhB,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,UAAU,EACV,YAAY,GACZ,MAAM,UAAU,CAAA;AAEjB,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA"}