timeback 0.0.0-alpha.2 → 0.1.0
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 +211 -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/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 +1137 -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/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.js +522 -0
- package/dist/server/adapters/types.d.ts +212 -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 +92 -28
|
@@ -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"}
|