@timeback/sdk 0.1.7 → 0.1.8

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 (109) hide show
  1. package/README.md +91 -2
  2. package/dist/chunk-07j8zre9.js +2 -0
  3. package/dist/chunk-3886xy48.js +8 -0
  4. package/dist/chunk-9se82640.js +1 -0
  5. package/dist/chunk-ahy54f2r.js +2 -0
  6. package/dist/chunk-ewsp6v3b.js +16 -0
  7. package/dist/chunk-j1xdrfqj.js +2 -0
  8. package/dist/chunk-qaa129bd.js +2 -0
  9. package/dist/chunk-qr0bbnsr.js +1 -0
  10. package/dist/chunk-rgbpvxbv.js +1 -0
  11. package/dist/chunk-whc53e0y.js +11 -0
  12. package/dist/client/adapters/react/hooks/types.d.ts +46 -0
  13. package/dist/client/adapters/react/hooks/types.d.ts.map +1 -1
  14. package/dist/client/adapters/react/hooks/useTimebackProfile.d.ts +42 -0
  15. package/dist/client/adapters/react/hooks/useTimebackProfile.d.ts.map +1 -0
  16. package/dist/client/adapters/react/index.d.ts +2 -1
  17. package/dist/client/adapters/react/index.d.ts.map +1 -1
  18. package/dist/client/adapters/react/index.js +2 -494
  19. package/dist/client/adapters/solid/index.d.ts +3 -0
  20. package/dist/client/adapters/solid/index.d.ts.map +1 -1
  21. package/dist/client/adapters/solid/index.ts +12 -0
  22. package/dist/client/adapters/solid/primitives/createTimebackProfile.d.ts +58 -0
  23. package/dist/client/adapters/solid/primitives/createTimebackProfile.d.ts.map +1 -0
  24. package/dist/client/adapters/solid/primitives/createTimebackProfile.ts +209 -0
  25. package/dist/client/adapters/solid/primitives/createTimebackVerification.d.ts +36 -0
  26. package/dist/client/adapters/solid/primitives/createTimebackVerification.d.ts.map +1 -0
  27. package/dist/client/adapters/solid/primitives/createTimebackVerification.ts +133 -0
  28. package/dist/client/adapters/solid/types.d.ts +86 -0
  29. package/dist/client/adapters/solid/types.d.ts.map +1 -0
  30. package/dist/client/adapters/solid/types.ts +85 -0
  31. package/dist/client/adapters/svelte/index.d.ts +2 -1
  32. package/dist/client/adapters/svelte/index.d.ts.map +1 -1
  33. package/dist/client/adapters/svelte/index.ts +11 -2
  34. package/dist/client/adapters/svelte/{stores.d.ts → stores/client.d.ts} +11 -9
  35. package/dist/client/adapters/svelte/stores/client.d.ts.map +1 -0
  36. package/dist/client/adapters/svelte/{stores.ts → stores/client.ts} +24 -52
  37. package/dist/client/adapters/svelte/stores/index.d.ts +10 -0
  38. package/dist/client/adapters/svelte/stores/index.d.ts.map +1 -0
  39. package/dist/client/adapters/svelte/stores/index.ts +22 -0
  40. package/dist/client/adapters/svelte/stores/profile.d.ts +66 -0
  41. package/dist/client/adapters/svelte/stores/profile.d.ts.map +1 -0
  42. package/dist/client/adapters/svelte/stores/profile.ts +168 -0
  43. package/dist/client/adapters/svelte/stores/verification.d.ts +43 -0
  44. package/dist/client/adapters/svelte/stores/verification.d.ts.map +1 -0
  45. package/dist/client/adapters/svelte/stores/verification.ts +126 -0
  46. package/dist/client/adapters/svelte/types.d.ts +35 -0
  47. package/dist/client/adapters/svelte/types.d.ts.map +1 -0
  48. package/dist/client/adapters/vue/composables/useTimebackProfile.d.ts +51 -0
  49. package/dist/client/adapters/vue/composables/useTimebackProfile.d.ts.map +1 -0
  50. package/dist/client/adapters/vue/composables/useTimebackProfile.ts +186 -0
  51. package/dist/client/adapters/vue/composables/useTimebackVerification.d.ts +44 -0
  52. package/dist/client/adapters/vue/composables/useTimebackVerification.d.ts.map +1 -0
  53. package/dist/client/adapters/vue/composables/useTimebackVerification.ts +128 -0
  54. package/dist/client/adapters/vue/index.d.ts +3 -0
  55. package/dist/client/adapters/vue/index.d.ts.map +1 -1
  56. package/dist/client/adapters/vue/index.ts +12 -1
  57. package/dist/client/adapters/vue/types.d.ts +86 -0
  58. package/dist/client/adapters/vue/types.d.ts.map +1 -0
  59. package/dist/client/adapters/vue/types.ts +85 -0
  60. package/dist/client/lib/activity/activity.class.d.ts +5 -5
  61. package/dist/client/lib/activity/activity.class.d.ts.map +1 -1
  62. package/dist/client/lib/user-cache.d.ts +39 -0
  63. package/dist/client/lib/user-cache.d.ts.map +1 -0
  64. package/dist/client/lib/user-cache.ts +168 -0
  65. package/dist/client/namespaces/activity.d.ts +2 -3
  66. package/dist/client/namespaces/activity.d.ts.map +1 -1
  67. package/dist/client.d.ts +1 -1
  68. package/dist/client.js +1 -257
  69. package/dist/edge.js +1 -86271
  70. package/dist/identity.js +1 -86131
  71. package/dist/index.js +22 -104883
  72. package/dist/server/adapters/express.js +1 -85973
  73. package/dist/server/adapters/native.js +2 -221
  74. package/dist/server/adapters/nextjs.js +1 -233
  75. package/dist/server/adapters/nuxt.js +1 -86046
  76. package/dist/server/adapters/solid-start.js +1 -85945
  77. package/dist/server/adapters/svelte-kit.js +1 -279
  78. package/dist/server/adapters/tanstack-start.js +1 -85918
  79. package/dist/server/handlers/activity/attempts.d.ts +51 -0
  80. package/dist/server/handlers/activity/attempts.d.ts.map +1 -0
  81. package/dist/server/handlers/activity/caliper.d.ts +46 -5
  82. package/dist/server/handlers/activity/caliper.d.ts.map +1 -1
  83. package/dist/server/handlers/activity/completion.d.ts +43 -0
  84. package/dist/server/handlers/activity/completion.d.ts.map +1 -0
  85. package/dist/server/handlers/activity/handler.d.ts +18 -1
  86. package/dist/server/handlers/activity/handler.d.ts.map +1 -1
  87. package/dist/server/handlers/activity/progress.d.ts +47 -0
  88. package/dist/server/handlers/activity/progress.d.ts.map +1 -0
  89. package/dist/server/handlers/activity/schema.d.ts +1 -2
  90. package/dist/server/handlers/activity/schema.d.ts.map +1 -1
  91. package/dist/server/handlers/activity/types.d.ts +1 -2
  92. package/dist/server/handlers/activity/types.d.ts.map +1 -1
  93. package/dist/server/lib/index.d.ts +1 -1
  94. package/dist/server/lib/index.d.ts.map +1 -1
  95. package/dist/server/lib/utils.d.ts +61 -0
  96. package/dist/server/lib/utils.d.ts.map +1 -1
  97. package/dist/server/timeback.d.ts.map +1 -1
  98. package/dist/server/types.d.ts +7 -1
  99. package/dist/server/types.d.ts.map +1 -1
  100. package/dist/shared/constants.d.ts +6 -0
  101. package/dist/shared/constants.d.ts.map +1 -1
  102. package/dist/shared/types.d.ts +62 -8
  103. package/dist/shared/types.d.ts.map +1 -1
  104. package/dist/shared/xp-calculator.d.ts +25 -0
  105. package/dist/shared/xp-calculator.d.ts.map +1 -0
  106. package/package.json +4 -2
  107. package/dist/client/adapters/svelte/stores.d.ts.map +0 -1
  108. package/dist/server/handlers/activity/gradebook.d.ts +0 -56
  109. package/dist/server/handlers/activity/gradebook.d.ts.map +0 -1
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Shared User Cache
3
+ *
4
+ * Internal module for in-flight deduplication and short-lived caching of
5
+ * verify and profile requests. Used by Solid, Svelte, and Vue adapters.
6
+ */
7
+
8
+ import type { TimebackProfile, TimebackVerifyResult } from '../../shared/types'
9
+ import type { TimebackClient } from '../timeback-client.class'
10
+
11
+ const VERIFY_CACHE_TTL_MS = 1500
12
+ const PROFILE_CACHE_TTL_MS = 5000
13
+
14
+ type VerifyCacheEntry = { atMs: number; result: TimebackVerifyResult }
15
+ type ProfileCacheEntry = { atMs: number; profile: TimebackProfile }
16
+
17
+ const verifyInFlight = new WeakMap<TimebackClient, Promise<TimebackVerifyResult>>()
18
+ const verifyCache = new WeakMap<TimebackClient, VerifyCacheEntry>()
19
+
20
+ const profileInFlight = new WeakMap<TimebackClient, Promise<TimebackProfile>>()
21
+ const profileCache = new WeakMap<TimebackClient, ProfileCacheEntry>()
22
+
23
+ /**
24
+ * Check whether a cached verification result is still fresh.
25
+ *
26
+ * @param entry - Cached entry (if any)
27
+ * @returns True if the cache entry exists and is within TTL
28
+ */
29
+ function isVerifyCacheFresh(entry: VerifyCacheEntry | undefined): entry is VerifyCacheEntry {
30
+ return !!entry && Date.now() - entry.atMs < VERIFY_CACHE_TTL_MS
31
+ }
32
+
33
+ /**
34
+ * Check whether a cached profile result is still fresh.
35
+ *
36
+ * @param entry - Cached entry (if any)
37
+ * @returns True if the cache entry exists and is within TTL
38
+ */
39
+ function isProfileCacheFresh(entry: ProfileCacheEntry | undefined): entry is ProfileCacheEntry {
40
+ return !!entry && Date.now() - entry.atMs < PROFILE_CACHE_TTL_MS
41
+ }
42
+
43
+ /**
44
+ * Verify the current user with in-flight dedupe and short-lived caching.
45
+ *
46
+ * @param timeback - Timeback client instance
47
+ * @param force - If true, bypass cache and in-flight reuse
48
+ * @returns Verify result
49
+ */
50
+ export async function verifyOnce(
51
+ timeback: TimebackClient,
52
+ force: boolean,
53
+ ): Promise<TimebackVerifyResult> {
54
+ if (!force) {
55
+ const cached = verifyCache.get(timeback)
56
+
57
+ if (isVerifyCacheFresh(cached)) {
58
+ return cached.result
59
+ }
60
+
61
+ const existing = verifyInFlight.get(timeback)
62
+
63
+ if (existing) {
64
+ return await existing
65
+ }
66
+ }
67
+
68
+ const p = timeback.user.verify().then(result => {
69
+ /**
70
+ * Guard against stale overwrites:
71
+ *
72
+ * If `force=true` triggers a newer request while an older one is still
73
+ * in-flight, the older promise may resolve later. Only let the most
74
+ * recent in-flight promise update the cache.
75
+ */
76
+ if (verifyInFlight.get(timeback) === p) {
77
+ verifyCache.set(timeback, { atMs: Date.now(), result })
78
+ }
79
+ return result
80
+ })
81
+
82
+ verifyInFlight.set(timeback, p)
83
+ try {
84
+ return await p
85
+ } finally {
86
+ /**
87
+ * Only remove the in-flight verification promise
88
+ * if it is still the most recent for this client instance.
89
+ */
90
+ if (verifyInFlight.get(timeback) === p) {
91
+ verifyInFlight.delete(timeback)
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Get cached verification result if fresh.
98
+ *
99
+ * @param timeback - Timeback client instance
100
+ * @returns Cached result or undefined
101
+ */
102
+ export function getVerifyCache(timeback: TimebackClient): TimebackVerifyResult | undefined {
103
+ const cached = verifyCache.get(timeback)
104
+ return isVerifyCacheFresh(cached) ? cached.result : undefined
105
+ }
106
+
107
+ /**
108
+ * Fetch the profile with in-flight dedupe and short-lived caching.
109
+ *
110
+ * @param timeback - Timeback client instance
111
+ * @param force - If true, bypass cache and in-flight reuse
112
+ * @returns The user's Timeback profile
113
+ */
114
+ export async function fetchProfileOnce(
115
+ timeback: TimebackClient,
116
+ force: boolean,
117
+ ): Promise<TimebackProfile> {
118
+ if (!force) {
119
+ const cached = profileCache.get(timeback)
120
+
121
+ if (isProfileCacheFresh(cached)) {
122
+ return cached.profile
123
+ }
124
+
125
+ const existing = profileInFlight.get(timeback)
126
+
127
+ if (existing) {
128
+ return await existing
129
+ }
130
+ }
131
+
132
+ const p = timeback.user.fetch().then(profile => {
133
+ /**
134
+ * Guard against stale overwrites:
135
+ *
136
+ * If `force=true` triggers a newer request while an older one is still
137
+ * in-flight, the older promise may resolve later. Only let the most
138
+ * recent in-flight promise update the cache.
139
+ */
140
+ if (profileInFlight.get(timeback) === p) {
141
+ profileCache.set(timeback, { atMs: Date.now(), profile })
142
+ }
143
+ return profile
144
+ })
145
+
146
+ profileInFlight.set(timeback, p)
147
+ try {
148
+ return await p
149
+ } finally {
150
+ /**
151
+ * Only remove the in-flight promise if it is still the most recent
152
+ */
153
+ if (profileInFlight.get(timeback) === p) {
154
+ profileInFlight.delete(timeback)
155
+ }
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Get cached profile result if fresh.
161
+ *
162
+ * @param timeback - Timeback client instance
163
+ * @returns Cached profile or undefined
164
+ */
165
+ export function getProfileCache(timeback: TimebackClient): TimebackProfile | undefined {
166
+ const cached = profileCache.get(timeback)
167
+ return isProfileCacheFresh(cached) ? cached.profile : undefined
168
+ }
@@ -25,7 +25,7 @@ export declare class ActivityManager {
25
25
  * @param params - Activity parameters
26
26
  * @returns Started activity instance
27
27
  *
28
- * @example
28
+ * @example Basic usage
29
29
  * ```typescript
30
30
  * const activity = timeback.activity.start({
31
31
  * id: 'lesson-1',
@@ -36,8 +36,7 @@ export declare class ActivityManager {
36
36
  * await activity.end({
37
37
  * totalQuestions: 10,
38
38
  * correctQuestions: 8,
39
- * attemptNumber: 1,
40
- * pctCompleteApp: 67,
39
+ * pctComplete: 67,
41
40
  * })
42
41
  * ```
43
42
  */
@@ -1 +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;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,KAAK,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CAEtC;CACD"}
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;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,KAAK,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CAEtC;CACD"}
package/dist/client.d.ts CHANGED
@@ -21,7 +21,7 @@
21
21
  * activity.resume()
22
22
  *
23
23
  * // End tracking with metrics
24
- * await activity.end({ totalQuestions: 10, correctQuestions: 8, attemptNumber: 1 })
24
+ * await activity.end({ totalQuestions: 10, correctQuestions: 8 })
25
25
  * ```
26
26
  */
27
27
  export { createClient, TimebackClient } from './client/index';
package/dist/client.js CHANGED
@@ -1,257 +1 @@
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
- VERIFY: "/user/verify"
13
- }
14
- };
15
-
16
- // src/client/lib/utils.ts
17
- function isBrowser() {
18
- return typeof window !== "undefined";
19
- }
20
- function getDefaultBaseURL() {
21
- if (!isBrowser()) {
22
- return;
23
- }
24
- return `${window.location.origin}${DEFAULT_BASE_PATH}`;
25
- }
26
-
27
- // src/client/lib/fetch.ts
28
- function getDefaultFetch() {
29
- const globalFetch = typeof globalThis === "undefined" ? undefined : globalThis.fetch;
30
- if (!globalFetch) {
31
- return;
32
- }
33
- return (input, init) => globalThis.fetch(input, init);
34
- }
35
-
36
- // src/client/lib/activity/activity.class.ts
37
- class Activity {
38
- params;
39
- sendActivity;
40
- _startedAt;
41
- _isPaused = false;
42
- _pausedAt;
43
- _totalPausedMs = 0;
44
- _ended = false;
45
- constructor(params, sendActivity) {
46
- this.params = params;
47
- this.sendActivity = sendActivity;
48
- this._startedAt = new Date;
49
- }
50
- get startedAt() {
51
- return this._startedAt;
52
- }
53
- get isPaused() {
54
- return this._isPaused;
55
- }
56
- get elapsedMs() {
57
- if (this._ended) {
58
- return 0;
59
- }
60
- const now = new Date;
61
- let elapsed = now.getTime() - this._startedAt.getTime() - this._totalPausedMs;
62
- if (this._isPaused && this._pausedAt) {
63
- elapsed -= now.getTime() - this._pausedAt.getTime();
64
- }
65
- return Math.max(0, elapsed);
66
- }
67
- _buildPayload(data) {
68
- const now = new Date;
69
- const pausedMs = this._totalPausedMs + (this._isPaused && this._pausedAt ? now.getTime() - this._pausedAt.getTime() : 0);
70
- const elapsedMs = now.getTime() - this._startedAt.getTime() - pausedMs;
71
- return {
72
- id: this.params.id,
73
- name: this.params.name,
74
- course: this.params.course,
75
- startedAt: this._startedAt.toISOString(),
76
- endedAt: now.toISOString(),
77
- elapsedMs: Math.max(0, elapsedMs),
78
- pausedMs,
79
- metrics: {
80
- totalQuestions: data.totalQuestions,
81
- correctQuestions: data.correctQuestions,
82
- ...data.xpEarned === undefined ? {} : { xpEarned: data.xpEarned },
83
- ...data.masteredUnits === undefined ? {} : { masteredUnits: data.masteredUnits }
84
- },
85
- ...data.attemptNumber === undefined ? {} : { attemptNumber: data.attemptNumber },
86
- ...data.pctCompleteApp === undefined ? {} : { pctCompleteApp: data.pctCompleteApp }
87
- };
88
- }
89
- pause() {
90
- if (this._isPaused || this._ended)
91
- return;
92
- this._isPaused = true;
93
- this._pausedAt = new Date;
94
- }
95
- resume() {
96
- if (!this._isPaused || this._ended || !this._pausedAt)
97
- return;
98
- this._totalPausedMs += new Date().getTime() - this._pausedAt.getTime();
99
- this._isPaused = false;
100
- this._pausedAt = undefined;
101
- }
102
- async end(data) {
103
- if (this._ended)
104
- return;
105
- this._ended = true;
106
- if (this._isPaused && this._pausedAt) {
107
- this._totalPausedMs += new Date().getTime() - this._pausedAt.getTime();
108
- this._isPaused = false;
109
- this._pausedAt = undefined;
110
- }
111
- const payload = this._buildPayload(data);
112
- await this.sendActivity(payload);
113
- }
114
- }
115
- // src/client/namespaces/activity.ts
116
- class ActivityManager {
117
- sendActivity;
118
- constructor(sendActivity) {
119
- this.sendActivity = sendActivity;
120
- }
121
- start(params) {
122
- return new Activity(params, this.sendActivity);
123
- }
124
- }
125
- // src/client/namespaces/auth.ts
126
- class Auth {
127
- getBaseURL;
128
- constructor(getBaseURL) {
129
- this.getBaseURL = getBaseURL;
130
- }
131
- signIn() {
132
- if (!isBrowser()) {
133
- throw new Error("signIn() requires a browser environment");
134
- }
135
- window.location.href = `${this.getBaseURL()}${ROUTES.IDENTITY.SIGNIN}`;
136
- }
137
- }
138
- // src/client/namespaces/user.ts
139
- class User {
140
- getBaseURL;
141
- fetchImpl;
142
- constructor(getBaseURL, fetchImpl) {
143
- this.getBaseURL = getBaseURL;
144
- this.fetchImpl = fetchImpl;
145
- }
146
- async fetch() {
147
- if (!isBrowser()) {
148
- throw new Error("user.fetch() requires a browser environment");
149
- }
150
- const response = await this.fetchImpl(`${this.getBaseURL()}${ROUTES.USER.ME}`, {
151
- method: "GET",
152
- credentials: "include"
153
- });
154
- if (!response.ok) {
155
- const errorResponse = await response.json().catch(() => ({ error: "Unknown error" }));
156
- throw new Error(errorResponse.error ?? "Failed to fetch user profile");
157
- }
158
- return response.json();
159
- }
160
- async verify() {
161
- if (!isBrowser()) {
162
- throw new Error("user.verify() requires a browser environment");
163
- }
164
- const response = await this.fetchImpl(`${this.getBaseURL()}${ROUTES.USER.VERIFY}`, {
165
- method: "GET",
166
- credentials: "include"
167
- });
168
- if (!response.ok) {
169
- const errorResponse = await response.json().catch(() => ({ error: "Unknown error" }));
170
- throw new Error(errorResponse.error ?? "Failed to verify Timeback user");
171
- }
172
- const data = await response.json();
173
- if (data.verified && data.timebackId) {
174
- return { verified: true, timebackId: data.timebackId };
175
- }
176
- return { verified: false };
177
- }
178
- }
179
- // src/client/timeback-client.class.ts
180
- class TimebackClient {
181
- activity;
182
- auth;
183
- user;
184
- _baseURL;
185
- _fetch;
186
- constructor(config = {}) {
187
- this._baseURL = config.baseURL;
188
- const baseFetch = config.fetch ?? getDefaultFetch();
189
- if (!baseFetch) {
190
- throw new Error("TimebackClient requires a fetch implementation. " + "Provide `fetch` in the constructor config for non-browser runtimes.");
191
- }
192
- const rawPlugins = config.plugins;
193
- const plugins = Array.isArray(rawPlugins) ? rawPlugins : rawPlugins ? [rawPlugins] : [];
194
- this._fetch = plugins.reduce((f, p) => p.wrapFetch(f), baseFetch);
195
- this.activity = new ActivityManager((payload) => this.sendActivity(payload));
196
- this.auth = new Auth(() => this.baseURL);
197
- this.user = new User(() => this.baseURL, this._fetch);
198
- }
199
- get baseURL() {
200
- if (!this._baseURL) {
201
- const resolved = getDefaultBaseURL();
202
- if (!resolved) {
203
- throw new Error("Timeback client requires a browser environment for default baseURL. " + "Provide an explicit baseURL for server-side usage.");
204
- }
205
- this._baseURL = resolved;
206
- }
207
- return this._baseURL;
208
- }
209
- async sendActivity(payload) {
210
- const response = await this._fetch(`${this.baseURL}${ROUTES.ACTIVITY}`, {
211
- method: "POST",
212
- headers: { "Content-Type": "application/json" },
213
- body: JSON.stringify(payload),
214
- credentials: "include"
215
- });
216
- if (!response.ok) {
217
- const errorResponse = await response.json().catch(() => ({ error: "Unknown error" }));
218
- throw new Error(errorResponse.error ?? "Failed to send activity");
219
- }
220
- }
221
- }
222
-
223
- // src/client/timeback-client.ts
224
- function createClient(config = {}) {
225
- const baseURL = config.baseURL ?? getDefaultBaseURL();
226
- return new TimebackClient({
227
- baseURL,
228
- fetch: config.fetch,
229
- plugins: config.plugins
230
- });
231
- }
232
- // src/client/auth/bearer.ts
233
- function bearer(options) {
234
- const headerName = options.headerName ?? "Authorization";
235
- const prefix = options.prefix ?? "Bearer ";
236
- return {
237
- wrapFetch(fetchImpl) {
238
- return async (input, init) => {
239
- const token = await options.getToken();
240
- if (!token) {
241
- throw new Error("Missing bearer token (are you authenticated yet?)");
242
- }
243
- const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined));
244
- if (!headers.has(headerName)) {
245
- headers.set(headerName, `${prefix}${token}`);
246
- }
247
- return fetchImpl(input, { ...init, headers });
248
- };
249
- }
250
- };
251
- }
252
- export {
253
- createClient,
254
- bearer,
255
- TimebackClient,
256
- Activity
257
- };
1
+ import{a as o,b as y,c as b}from"./chunk-ahy54f2r.js";function r(e){let i=e.headerName??"Authorization",k=e.prefix??"Bearer ";return{wrapFetch(s){return async(t,m)=>{let a=await e.getToken();if(!a)throw Error("Missing bearer token (are you authenticated yet?)");let c=new Headers(m?.headers??(t instanceof Request?t.headers:void 0));if(!c.has(i))c.set(i,`${k}${a}`);return s(t,{...m,headers:c})}}}}export{b as createClient,r as bearer,y as TimebackClient,o as Activity};