@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,186 @@
1
+ /**
2
+ * useTimebackProfile
3
+ *
4
+ * Vue composable for fetching the current user's Timeback profile.
5
+ *
6
+ * This composable uses `useTimebackVerification` internally and only fetches
7
+ * the profile when the user is verified (i.e., exists in Timeback).
8
+ */
9
+
10
+ import { computed, ref, watch } from 'vue'
11
+
12
+ import { fetchProfileOnce, getProfileCache } from '../../../lib/user-cache'
13
+ import { useTimeback } from '../provider'
14
+ import { useTimebackVerification } from './useTimebackVerification'
15
+
16
+ import type { ComputedRef, Ref } from 'vue'
17
+ import type { TimebackProfileState, UseTimebackProfileOptions } from '../types'
18
+
19
+ /**
20
+ * Fetch the current user's Timeback profile.
21
+ *
22
+ * This composable internally uses `useTimebackVerification` to ensure the user
23
+ * is verified before fetching. When `auto: true`, it automatically fetches
24
+ * the profile once verified. Otherwise, call `fetchProfile()` manually.
25
+ *
26
+ * @param options - Composable options
27
+ * @param options.enabled - If false, the composable does nothing and stays in idle state. Defaults to true.
28
+ * @param options.auto - If true, automatically fetch once verified. Defaults to false.
29
+ * @returns Profile state and fetch methods
30
+ *
31
+ * @example
32
+ * ```vue
33
+ * <script setup>
34
+ * import { useTimebackProfile } from '@timeback/sdk/vue'
35
+ *
36
+ * // Manual fetch
37
+ * const { state, canFetch, fetchProfile } = useTimebackProfile()
38
+ *
39
+ * // Or auto-fetch
40
+ * // const { state } = useTimebackProfile({ auto: true })
41
+ * </script>
42
+ *
43
+ * <template>
44
+ * <div v-if="state.status === 'loaded'">
45
+ * XP: {{ state.profile.xp }}
46
+ * </div>
47
+ * <button v-else @click="fetchProfile" :disabled="!canFetch">
48
+ * {{ state.status === 'loading' ? 'Loading...' : 'Load Profile' }}
49
+ * </button>
50
+ * </template>
51
+ * ```
52
+ */
53
+ export function useTimebackProfile(options: UseTimebackProfileOptions = {}): {
54
+ state: Ref<TimebackProfileState>
55
+ canFetch: ComputedRef<boolean>
56
+ fetchProfile: () => void
57
+ refresh: () => void
58
+ } {
59
+ const { enabled = true, auto = false } = options
60
+
61
+ const timebackRef = useTimeback()
62
+ const { state: verificationState } = useTimebackVerification({ enabled })
63
+
64
+ const state = ref<TimebackProfileState>({ status: 'idle' }) as Ref<TimebackProfileState>
65
+ const fetchNonce = ref(0)
66
+ const refreshNonce = ref(0)
67
+
68
+ let lastHandledFetchNonce = 0
69
+ let lastHandledRefreshNonce = 0
70
+ let autoTriggered = false
71
+
72
+ const canFetch = computed(
73
+ () => enabled && verificationState.value.status === 'verified' && !!timebackRef.value,
74
+ )
75
+
76
+ const fetchProfile = () => {
77
+ if (!canFetch.value) {
78
+ return
79
+ }
80
+
81
+ fetchNonce.value++
82
+ }
83
+
84
+ const refresh = () => {
85
+ if (!canFetch.value) {
86
+ return
87
+ }
88
+
89
+ refreshNonce.value++
90
+ }
91
+
92
+ watch(
93
+ [verificationState, fetchNonce, refreshNonce, () => timebackRef.value],
94
+ async ([verification, fetchN, refreshN, timeback], _prev, onCleanup) => {
95
+ if (!enabled) {
96
+ state.value = { status: 'idle' }
97
+
98
+ return
99
+ }
100
+
101
+ let cancelled = false
102
+
103
+ onCleanup(() => {
104
+ cancelled = true
105
+ })
106
+
107
+ if (verification.status !== 'verified') {
108
+ if (state.value.status !== 'idle') {
109
+ state.value = { status: 'idle' }
110
+ }
111
+
112
+ autoTriggered = false
113
+
114
+ return
115
+ }
116
+
117
+ if (auto && !autoTriggered && fetchN === 0 && refreshN === 0) {
118
+ autoTriggered = true
119
+ fetchNonce.value = 1
120
+ return
121
+ }
122
+
123
+ if (fetchN === 0 && refreshN === 0) {
124
+ return
125
+ }
126
+
127
+ const isNewFetch = fetchN > lastHandledFetchNonce
128
+ const isNewRefresh = refreshN > lastHandledRefreshNonce
129
+ const force = isNewRefresh
130
+
131
+ if (!isNewFetch && !isNewRefresh) {
132
+ if (timeback) {
133
+ const cached = getProfileCache(timeback)
134
+
135
+ if (cached) {
136
+ state.value = { status: 'loaded', profile: cached }
137
+
138
+ return
139
+ }
140
+ }
141
+
142
+ return
143
+ }
144
+
145
+ if (timeback && !force) {
146
+ const cached = getProfileCache(timeback)
147
+
148
+ if (cached) {
149
+ state.value = { status: 'loaded', profile: cached }
150
+ lastHandledFetchNonce = fetchN
151
+
152
+ return
153
+ }
154
+ }
155
+
156
+ state.value = { status: 'loading' }
157
+
158
+ try {
159
+ if (!timeback) {
160
+ return
161
+ }
162
+
163
+ lastHandledFetchNonce = fetchN
164
+ lastHandledRefreshNonce = refreshN
165
+
166
+ const profile = await fetchProfileOnce(timeback, force)
167
+
168
+ if (cancelled) {
169
+ return
170
+ }
171
+
172
+ state.value = { status: 'loaded', profile }
173
+ } catch (err) {
174
+ if (!cancelled) {
175
+ state.value = {
176
+ status: 'error',
177
+ message: err instanceof Error ? err.message : 'Failed to fetch profile',
178
+ }
179
+ }
180
+ }
181
+ },
182
+ { immediate: true },
183
+ )
184
+
185
+ return { state, canFetch, fetchProfile, refresh }
186
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * useTimebackVerification
3
+ *
4
+ * Vue composable for checking whether the current user can be verified in Timeback.
5
+ *
6
+ * This is a lightweight check (backed by `/api/timeback/user/verify`) and is
7
+ * intended for partner gating flows (e.g., "free for Timeback users").
8
+ */
9
+ import type { Ref } from 'vue';
10
+ import type { TimebackVerificationState, UseTimebackVerificationOptions } from '../types';
11
+ /**
12
+ * Verify the current user against Timeback.
13
+ *
14
+ * The composable runs automatically once the Timeback client is available, and
15
+ * provides a `refresh()` method to retry.
16
+ *
17
+ * @param options - Composable options
18
+ * @param options.enabled - If false, the composable does nothing and stays in loading state.
19
+ * @returns Verification state and a refresh method
20
+ *
21
+ * @example
22
+ * ```vue
23
+ * <script setup>
24
+ * import { useTimebackVerification } from '@timeback/sdk/vue'
25
+ *
26
+ * const { state, refresh } = useTimebackVerification()
27
+ * </script>
28
+ *
29
+ * <template>
30
+ * <div v-if="state.status === 'verified'">
31
+ * Verified as {{ state.timebackId }}
32
+ * </div>
33
+ * <div v-else-if="state.status === 'loading'">
34
+ * Verifying...
35
+ * </div>
36
+ * <button @click="refresh">Refresh</button>
37
+ * </template>
38
+ * ```
39
+ */
40
+ export declare function useTimebackVerification(options?: UseTimebackVerificationOptions): {
41
+ state: Ref<TimebackVerificationState>;
42
+ refresh: () => void;
43
+ };
44
+ //# sourceMappingURL=useTimebackVerification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTimebackVerification.d.ts","sourceRoot":"","sources":["../../../../../src/client/adapters/vue/composables/useTimebackVerification.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAE9B,OAAO,KAAK,EAAE,yBAAyB,EAAE,8BAA8B,EAAE,MAAM,UAAU,CAAA;AAczF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,uBAAuB,CACtC,OAAO,GAAE,8BAAmC,GAC1C;IACF,KAAK,EAAE,GAAG,CAAC,yBAAyB,CAAC,CAAA;IACrC,OAAO,EAAE,MAAM,IAAI,CAAA;CACnB,CA+DA"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * useTimebackVerification
3
+ *
4
+ * Vue composable for checking whether the current user can be verified in Timeback.
5
+ *
6
+ * This is a lightweight check (backed by `/api/timeback/user/verify`) and is
7
+ * intended for partner gating flows (e.g., "free for Timeback users").
8
+ */
9
+
10
+ import { ref, watch } from 'vue'
11
+
12
+ import { getVerifyCache, verifyOnce } from '../../../lib/user-cache'
13
+ import { useTimeback } from '../provider'
14
+
15
+ import type { Ref } from 'vue'
16
+ import type { TimebackVerifyResult } from '../../../../shared/types'
17
+ import type { TimebackVerificationState, UseTimebackVerificationOptions } from '../types'
18
+
19
+ /**
20
+ * Convert a verify result into a composable-friendly state machine.
21
+ *
22
+ * @param result - Raw verify result from the SDK client
23
+ * @returns Mapped verification state
24
+ */
25
+ function toState(result: TimebackVerifyResult): TimebackVerificationState {
26
+ return result.verified
27
+ ? { status: 'verified', timebackId: result.timebackId }
28
+ : { status: 'unverified' }
29
+ }
30
+
31
+ /**
32
+ * Verify the current user against Timeback.
33
+ *
34
+ * The composable runs automatically once the Timeback client is available, and
35
+ * provides a `refresh()` method to retry.
36
+ *
37
+ * @param options - Composable options
38
+ * @param options.enabled - If false, the composable does nothing and stays in loading state.
39
+ * @returns Verification state and a refresh method
40
+ *
41
+ * @example
42
+ * ```vue
43
+ * <script setup>
44
+ * import { useTimebackVerification } from '@timeback/sdk/vue'
45
+ *
46
+ * const { state, refresh } = useTimebackVerification()
47
+ * </script>
48
+ *
49
+ * <template>
50
+ * <div v-if="state.status === 'verified'">
51
+ * Verified as {{ state.timebackId }}
52
+ * </div>
53
+ * <div v-else-if="state.status === 'loading'">
54
+ * Verifying...
55
+ * </div>
56
+ * <button @click="refresh">Refresh</button>
57
+ * </template>
58
+ * ```
59
+ */
60
+ export function useTimebackVerification(
61
+ options: UseTimebackVerificationOptions = {},
62
+ ): {
63
+ state: Ref<TimebackVerificationState>
64
+ refresh: () => void
65
+ } {
66
+ const enabled = options.enabled ?? true
67
+ const timebackRef = useTimeback()
68
+
69
+ const state = ref<TimebackVerificationState>({ status: 'loading' }) as Ref<TimebackVerificationState>
70
+ const refreshNonce = ref(0)
71
+
72
+ let lastHandledRefreshNonce = 0
73
+
74
+ const refresh = () => {
75
+ if (!enabled) return
76
+ refreshNonce.value++
77
+ }
78
+
79
+ watch(
80
+ [() => timebackRef.value, refreshNonce],
81
+ async ([timeback, nonce], _prev, onCleanup) => {
82
+ if (!enabled) return
83
+
84
+ let cancelled = false
85
+
86
+ onCleanup(() => {
87
+ cancelled = true
88
+ })
89
+
90
+ const force = nonce > lastHandledRefreshNonce
91
+
92
+ if (timeback && !force) {
93
+ const cached = getVerifyCache(timeback)
94
+
95
+ if (cached) {
96
+ state.value = toState(cached)
97
+ return
98
+ }
99
+ }
100
+
101
+ state.value = { status: 'loading' }
102
+
103
+ try {
104
+ if (!timeback) return
105
+
106
+ if (force) {
107
+ lastHandledRefreshNonce = nonce
108
+ }
109
+
110
+ const result = await verifyOnce(timeback, force)
111
+
112
+ if (cancelled) return
113
+
114
+ state.value = toState(result)
115
+ } catch (err) {
116
+ if (!cancelled) {
117
+ state.value = {
118
+ status: 'error',
119
+ message: err instanceof Error ? err.message : 'Failed to verify Timeback user',
120
+ }
121
+ }
122
+ }
123
+ },
124
+ { immediate: true },
125
+ )
126
+
127
+ return { state, refresh }
128
+ }
@@ -37,6 +37,9 @@
37
37
  export { Activity, createClient, TimebackClient } from '@timeback/sdk/client';
38
38
  export type { ActivityMetrics, ActivityParams, TimebackIdentity } from '@timeback/sdk/client';
39
39
  export { TimebackProvider, useTimeback } from './provider';
40
+ export { useTimebackVerification } from './composables/useTimebackVerification';
41
+ export { useTimebackProfile } from './composables/useTimebackProfile';
42
+ export type { TimebackProfileState, TimebackVerificationState, UseTimebackProfileOptions, UseTimebackProfileResult, UseTimebackVerificationOptions, UseTimebackVerificationResult, } from './types';
40
43
  export { default as SignInButton } from './SignInButton.vue';
41
44
  export type { SignInButtonProps } from './SignInButton.vue';
42
45
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/vue/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC7E,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG7F,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG1D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/vue/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC7E,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG7F,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,YAAY,EACX,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,8BAA8B,EAC9B,6BAA6B,GAC7B,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA"}
@@ -35,13 +35,24 @@
35
35
  * ```
36
36
  */
37
37
 
38
- // Re-export from timeback/client for convenience
39
38
  export { Activity, createClient, TimebackClient } from '@timeback/sdk/client'
40
39
  export type { ActivityMetrics, ActivityParams, TimebackIdentity } from '@timeback/sdk/client'
41
40
 
42
41
  // Vue-specific
43
42
  export { TimebackProvider, useTimeback } from './provider'
44
43
 
44
+ // Composables
45
+ export { useTimebackVerification } from './composables/useTimebackVerification'
46
+ export { useTimebackProfile } from './composables/useTimebackProfile'
47
+ export type {
48
+ TimebackProfileState,
49
+ TimebackVerificationState,
50
+ UseTimebackProfileOptions,
51
+ UseTimebackProfileResult,
52
+ UseTimebackVerificationOptions,
53
+ UseTimebackVerificationResult,
54
+ } from './types'
55
+
45
56
  // Components
46
57
  export { default as SignInButton } from './SignInButton.vue'
47
58
  export type { SignInButtonProps } from './SignInButton.vue'
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Vue Types
3
+ *
4
+ * Types for Vue-specific composables.
5
+ */
6
+ import type { TimebackProfile } from '../../../shared/types';
7
+ /**
8
+ * Verification state for the current user.
9
+ */
10
+ export type TimebackVerificationState = {
11
+ status: 'loading';
12
+ } | {
13
+ status: 'verified';
14
+ timebackId: string;
15
+ } | {
16
+ status: 'unverified';
17
+ } | {
18
+ status: 'error';
19
+ message: string;
20
+ };
21
+ /**
22
+ * Profile state for the current user.
23
+ */
24
+ export type TimebackProfileState = {
25
+ status: 'idle';
26
+ } | {
27
+ status: 'loading';
28
+ } | {
29
+ status: 'loaded';
30
+ profile: TimebackProfile;
31
+ } | {
32
+ status: 'error';
33
+ message: string;
34
+ };
35
+ /**
36
+ * Options for the useTimebackVerification composable.
37
+ */
38
+ export interface UseTimebackVerificationOptions {
39
+ /**
40
+ * If false, the composable does nothing and stays in loading state.
41
+ *
42
+ * @default true
43
+ */
44
+ enabled?: boolean;
45
+ }
46
+ /**
47
+ * Return value of the useTimebackVerification composable.
48
+ */
49
+ export interface UseTimebackVerificationResult {
50
+ /** Current verification state (reactive ref) */
51
+ state: TimebackVerificationState;
52
+ /** Force a re-verification. No-op if not enabled. */
53
+ refresh: () => void;
54
+ }
55
+ /**
56
+ * Options for the useTimebackProfile composable.
57
+ */
58
+ export interface UseTimebackProfileOptions {
59
+ /**
60
+ * If false, the composable does nothing and stays in idle state.
61
+ *
62
+ * @default true
63
+ */
64
+ enabled?: boolean;
65
+ /**
66
+ * If true, automatically fetch the profile once the user is verified.
67
+ * If false, you must call `fetchProfile()` manually.
68
+ *
69
+ * @default false
70
+ */
71
+ auto?: boolean;
72
+ }
73
+ /**
74
+ * Return value of the useTimebackProfile composable.
75
+ */
76
+ export interface UseTimebackProfileResult {
77
+ /** Current profile state (reactive ref) */
78
+ state: TimebackProfileState;
79
+ /** Whether the profile can be fetched (user is verified and client is ready) */
80
+ canFetch: boolean;
81
+ /** Manually trigger a profile fetch. No-op if canFetch is false. */
82
+ fetchProfile: () => void;
83
+ /** Force a re-fetch even if already loaded. No-op if canFetch is false. */
84
+ refresh: () => void;
85
+ }
86
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/vue/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAE5D;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAClC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvC;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAC7B;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvC;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC9C;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC7C,gDAAgD;IAChD,KAAK,EAAE,yBAAyB,CAAA;IAEhC,qDAAqD;IACrD,OAAO,EAAE,MAAM,IAAI,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC,2CAA2C;IAC3C,KAAK,EAAE,oBAAoB,CAAA;IAE3B,gFAAgF;IAChF,QAAQ,EAAE,OAAO,CAAA;IAEjB,oEAAoE;IACpE,YAAY,EAAE,MAAM,IAAI,CAAA;IAExB,2EAA2E;IAC3E,OAAO,EAAE,MAAM,IAAI,CAAA;CACnB"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Vue Types
3
+ *
4
+ * Types for Vue-specific composables.
5
+ */
6
+
7
+ import type { TimebackProfile } from '../../../shared/types'
8
+
9
+ /**
10
+ * Verification state for the current user.
11
+ */
12
+ export type TimebackVerificationState =
13
+ | { status: 'loading' }
14
+ | { status: 'verified'; timebackId: string }
15
+ | { status: 'unverified' }
16
+ | { status: 'error'; message: string }
17
+
18
+ /**
19
+ * Profile state for the current user.
20
+ */
21
+ export type TimebackProfileState =
22
+ | { status: 'idle' }
23
+ | { status: 'loading' }
24
+ | { status: 'loaded'; profile: TimebackProfile }
25
+ | { status: 'error'; message: string }
26
+
27
+ /**
28
+ * Options for the useTimebackVerification composable.
29
+ */
30
+ export interface UseTimebackVerificationOptions {
31
+ /**
32
+ * If false, the composable does nothing and stays in loading state.
33
+ *
34
+ * @default true
35
+ */
36
+ enabled?: boolean
37
+ }
38
+
39
+ /**
40
+ * Return value of the useTimebackVerification composable.
41
+ */
42
+ export interface UseTimebackVerificationResult {
43
+ /** Current verification state (reactive ref) */
44
+ state: TimebackVerificationState
45
+
46
+ /** Force a re-verification. No-op if not enabled. */
47
+ refresh: () => void
48
+ }
49
+
50
+ /**
51
+ * Options for the useTimebackProfile composable.
52
+ */
53
+ export interface UseTimebackProfileOptions {
54
+ /**
55
+ * If false, the composable does nothing and stays in idle state.
56
+ *
57
+ * @default true
58
+ */
59
+ enabled?: boolean
60
+
61
+ /**
62
+ * If true, automatically fetch the profile once the user is verified.
63
+ * If false, you must call `fetchProfile()` manually.
64
+ *
65
+ * @default false
66
+ */
67
+ auto?: boolean
68
+ }
69
+
70
+ /**
71
+ * Return value of the useTimebackProfile composable.
72
+ */
73
+ export interface UseTimebackProfileResult {
74
+ /** Current profile state (reactive ref) */
75
+ state: TimebackProfileState
76
+
77
+ /** Whether the profile can be fetched (user is verified and client is ready) */
78
+ canFetch: boolean
79
+
80
+ /** Manually trigger a profile fetch. No-op if canFetch is false. */
81
+ fetchProfile: () => void
82
+
83
+ /** Force a re-fetch even if already loaded. No-op if canFetch is false. */
84
+ refresh: () => void
85
+ }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Client-side activity tracking logic.
5
5
  */
6
- import type { ActivityEndPayload, ActivityMetrics, ActivityParams } from '../../../shared/types';
6
+ import type { ActivityEndData, ActivityEndPayload, ActivityParams } from '../../../shared/types';
7
7
  /**
8
8
  * Activity tracker that tracks time spent on an activity.
9
9
  *
@@ -51,10 +51,10 @@ export declare class Activity {
51
51
  * Useful for "preview" flows in examples where you want to inspect the payload
52
52
  * that would be POSTed to the server without calling `end()`.
53
53
  *
54
- * @param data - Activity completion data (metrics + optional metadata)
54
+ * @param data - Activity completion data (metrics + optional time override)
55
55
  * @returns Activity end payload
56
56
  */
57
- _buildPayload(data: ActivityMetrics & Pick<Partial<ActivityEndPayload>, 'attemptNumber' | 'pctCompleteApp'>): ActivityEndPayload;
57
+ _buildPayload(data: ActivityEndData): ActivityEndPayload;
58
58
  /**
59
59
  * Pause the activity timer.
60
60
  */
@@ -66,8 +66,8 @@ export declare class Activity {
66
66
  /**
67
67
  * End the activity and send to server.
68
68
  *
69
- * @param data - Activity completion data (metrics + optional metadata)
69
+ * @param data - Activity completion data (metrics + optional time override)
70
70
  */
71
- end(data: ActivityMetrics & Pick<Partial<ActivityEndPayload>, 'attemptNumber' | 'pctCompleteApp'>): Promise<void>;
71
+ end(data: ActivityEndData): Promise<void>;
72
72
  }
73
73
  //# sourceMappingURL=activity.class.d.ts.map
@@ -1 +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;;;;;GAKG;AACH,qBAAa,QAAQ;IAgBnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAhB9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAM;IACjC,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,EAG7E;IAED;;;;OAIG;IACH,IAAI,SAAS,IAAI,IAAI,CAEpB;IAED;;;;OAIG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;OAIG;IACH,IAAI,SAAS,IAAI,MAAM,CAatB;IAED;;;;;;;;OAQG;IACH,aAAa,CACZ,IAAI,EAAE,eAAe,GACpB,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,eAAe,GAAG,gBAAgB,CAAC,GACpE,kBAAkB,CAyBpB;IAED;;OAEG;IACH,KAAK,IAAI,IAAI,CAIZ;IAED;;OAEG;IACH,MAAM,IAAI,IAAI,CAKb;IAED;;;;OAIG;IACG,GAAG,CACR,IAAI,EAAE,eAAe,GACpB,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,eAAe,GAAG,gBAAgB,CAAC,GACpE,OAAO,CAAC,IAAI,CAAC,CAaf;CACD"}
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,eAAe,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEhG;;;;;GAKG;AACH,qBAAa,QAAQ;IAgBnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAhB9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAM;IACjC,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,EAG7E;IAED;;;;OAIG;IACH,IAAI,SAAS,IAAI,IAAI,CAEpB;IAED;;;;OAIG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;OAIG;IACH,IAAI,SAAS,IAAI,MAAM,CAatB;IAED;;;;;;;;OAQG;IACH,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,kBAAkB,CAiDvD;IAED;;OAEG;IACH,KAAK,IAAI,IAAI,CAIZ;IAED;;OAEG;IACH,MAAM,IAAI,IAAI,CAKb;IAED;;;;OAIG;IACG,GAAG,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAa9C;CACD"}
@@ -0,0 +1,39 @@
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
+ import type { TimebackProfile, TimebackVerifyResult } from '../../shared/types';
8
+ import type { TimebackClient } from '../timeback-client.class';
9
+ /**
10
+ * Verify the current user with in-flight dedupe and short-lived caching.
11
+ *
12
+ * @param timeback - Timeback client instance
13
+ * @param force - If true, bypass cache and in-flight reuse
14
+ * @returns Verify result
15
+ */
16
+ export declare function verifyOnce(timeback: TimebackClient, force: boolean): Promise<TimebackVerifyResult>;
17
+ /**
18
+ * Get cached verification result if fresh.
19
+ *
20
+ * @param timeback - Timeback client instance
21
+ * @returns Cached result or undefined
22
+ */
23
+ export declare function getVerifyCache(timeback: TimebackClient): TimebackVerifyResult | undefined;
24
+ /**
25
+ * Fetch the profile with in-flight dedupe and short-lived caching.
26
+ *
27
+ * @param timeback - Timeback client instance
28
+ * @param force - If true, bypass cache and in-flight reuse
29
+ * @returns The user's Timeback profile
30
+ */
31
+ export declare function fetchProfileOnce(timeback: TimebackClient, force: boolean): Promise<TimebackProfile>;
32
+ /**
33
+ * Get cached profile result if fresh.
34
+ *
35
+ * @param timeback - Timeback client instance
36
+ * @returns Cached profile or undefined
37
+ */
38
+ export declare function getProfileCache(timeback: TimebackClient): TimebackProfile | undefined;
39
+ //# sourceMappingURL=user-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-cache.d.ts","sourceRoot":"","sources":["../../../src/client/lib/user-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAkC9D;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC/B,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,OAAO,GACZ,OAAO,CAAC,oBAAoB,CAAC,CAyC/B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,cAAc,GAAG,oBAAoB,GAAG,SAAS,CAGzF;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACrC,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,OAAO,GACZ,OAAO,CAAC,eAAe,CAAC,CAwC1B;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,eAAe,GAAG,SAAS,CAGrF"}