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.
- package/README.md +378 -7
- package/dist/client/adapters/react/SignInButton.d.ts +60 -0
- package/dist/client/adapters/react/SignInButton.d.ts.map +1 -0
- package/dist/client/adapters/react/index.d.ts +43 -0
- package/dist/client/adapters/react/index.d.ts.map +1 -0
- package/dist/client/adapters/react/index.js +478 -0
- package/dist/client/adapters/react/provider.d.ts +74 -0
- package/dist/client/adapters/react/provider.d.ts.map +1 -0
- package/dist/client/adapters/solid/SignInButton.d.ts +52 -0
- package/dist/client/adapters/solid/SignInButton.d.ts.map +1 -0
- package/dist/client/adapters/solid/SignInButton.tsx +321 -0
- package/dist/client/adapters/solid/context.d.ts +73 -0
- package/dist/client/adapters/solid/context.d.ts.map +1 -0
- package/dist/client/adapters/solid/context.tsx +91 -0
- package/dist/client/adapters/solid/index.d.ts +42 -0
- package/dist/client/adapters/solid/index.d.ts.map +1 -0
- package/dist/client/adapters/solid/index.ts +46 -0
- package/dist/client/adapters/svelte/SignInButton.svelte +234 -0
- package/dist/client/adapters/svelte/SignInButton.svelte.d.ts +24 -0
- package/dist/client/adapters/svelte/index.d.ts +33 -0
- package/dist/client/adapters/svelte/index.d.ts.map +1 -0
- package/dist/client/adapters/svelte/index.ts +38 -0
- package/dist/client/adapters/svelte/stores.d.ts +62 -0
- package/dist/client/adapters/svelte/stores.d.ts.map +1 -0
- package/dist/client/adapters/svelte/stores.ts +139 -0
- package/dist/client/adapters/vue/SignInButton.vue +260 -0
- package/dist/client/adapters/vue/SignInButton.vue.d.ts +53 -0
- package/dist/client/adapters/vue/index.d.ts +43 -0
- package/dist/client/adapters/vue/index.d.ts.map +1 -0
- package/dist/client/adapters/vue/index.ts +48 -0
- package/dist/client/adapters/vue/provider.d.ts +94 -0
- package/dist/client/adapters/vue/provider.d.ts.map +1 -0
- package/dist/client/adapters/vue/provider.ts +147 -0
- package/dist/client/index.d.ts +9 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/lib/activity/activity.class.d.ts +73 -0
- package/dist/client/lib/activity/activity.class.d.ts.map +1 -0
- package/dist/client/lib/activity/activity.d.ts +16 -0
- package/dist/client/lib/activity/activity.d.ts.map +1 -0
- package/dist/client/lib/activity/index.d.ts +6 -0
- package/dist/client/lib/activity/index.d.ts.map +1 -0
- package/dist/client/lib/utils.d.ts +20 -0
- package/dist/client/lib/utils.d.ts.map +1 -0
- package/dist/client/namespaces/activity.d.ts +37 -0
- package/dist/client/namespaces/activity.d.ts.map +1 -0
- package/dist/client/namespaces/auth.d.ts +33 -0
- package/dist/client/namespaces/auth.d.ts.map +1 -0
- package/dist/client/namespaces/index.d.ts +7 -0
- package/dist/client/namespaces/index.d.ts.map +1 -0
- package/dist/client/namespaces/user.d.ts +29 -0
- package/dist/client/namespaces/user.d.ts.map +1 -0
- package/dist/client/timeback-client.class.d.ts +37 -0
- package/dist/client/timeback-client.class.d.ts.map +1 -0
- package/dist/client/timeback-client.d.ts +29 -0
- package/dist/client/timeback-client.d.ts.map +1 -0
- package/dist/client.d.ts +30 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +198 -0
- package/dist/index.d.ts +27 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1373 -11
- package/dist/server/adapters/express.d.ts +62 -0
- package/dist/server/adapters/express.d.ts.map +1 -0
- package/dist/server/adapters/express.js +565 -0
- package/dist/server/adapters/native.d.ts +45 -0
- package/dist/server/adapters/native.d.ts.map +1 -0
- package/dist/server/adapters/native.js +509 -0
- package/dist/server/adapters/nextjs.d.ts +30 -0
- package/dist/server/adapters/nextjs.d.ts.map +1 -0
- package/dist/server/adapters/nextjs.js +521 -0
- package/dist/server/adapters/nuxt.d.ts +96 -0
- package/dist/server/adapters/nuxt.d.ts.map +1 -0
- package/dist/server/adapters/nuxt.js +663 -0
- package/dist/server/adapters/solid-start.d.ts +61 -0
- package/dist/server/adapters/solid-start.d.ts.map +1 -0
- package/dist/server/adapters/solid-start.js +551 -0
- package/dist/server/adapters/svelte-kit.d.ts +82 -0
- package/dist/server/adapters/svelte-kit.d.ts.map +1 -0
- package/dist/server/adapters/svelte-kit.js +572 -0
- package/dist/server/adapters/tanstack-start.d.ts +40 -0
- package/dist/server/adapters/tanstack-start.d.ts.map +1 -0
- package/dist/server/adapters/tanstack-start.js +522 -0
- package/dist/server/adapters/types.d.ts +280 -0
- package/dist/server/adapters/types.d.ts.map +1 -0
- package/dist/server/adapters/utils.d.ts +15 -0
- package/dist/server/adapters/utils.d.ts.map +1 -0
- package/dist/server/handlers/activity.d.ts +28 -0
- package/dist/server/handlers/activity.d.ts.map +1 -0
- package/dist/server/handlers/identity.d.ts +24 -0
- package/dist/server/handlers/identity.d.ts.map +1 -0
- package/dist/server/handlers/index.d.ts +9 -0
- package/dist/server/handlers/index.d.ts.map +1 -0
- package/dist/server/handlers/user.d.ts +30 -0
- package/dist/server/handlers/user.d.ts.map +1 -0
- package/dist/server/index.d.ts +10 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/lib/index.d.ts +9 -0
- package/dist/server/lib/index.d.ts.map +1 -0
- package/dist/server/lib/logger.d.ts +21 -0
- package/dist/server/lib/logger.d.ts.map +1 -0
- package/dist/server/lib/oidc.d.ts +76 -0
- package/dist/server/lib/oidc.d.ts.map +1 -0
- package/dist/server/lib/utils.d.ts +39 -0
- package/dist/server/lib/utils.d.ts.map +1 -0
- package/dist/server/timeback.d.ts +48 -0
- package/dist/server/timeback.d.ts.map +1 -0
- package/dist/server/types.d.ts +300 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/shared/constants.d.ts +18 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/types.d.ts +100 -0
- package/dist/shared/types.d.ts.map +1 -0
- 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 @@
|
|
|
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 @@
|
|
|
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"}
|
package/dist/client.d.ts
ADDED
|
@@ -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
|
-
*
|
|
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
|
|
5
|
-
|
|
6
|
-
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|