@lssm/example.learning-journey-registry 1.41.0 → 1.42.2

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 (79) hide show
  1. package/.turbo/turbo-build$colon$bundle.log +50 -0
  2. package/.turbo/turbo-build.log +45 -47
  3. package/CHANGELOG.md +64 -0
  4. package/LICENSE +21 -0
  5. package/README.md +3 -0
  6. package/dist/api-types.d.ts +41 -0
  7. package/dist/api-types.d.ts.map +1 -0
  8. package/dist/api.d.ts +13 -0
  9. package/dist/api.d.ts.map +1 -0
  10. package/dist/api.js +171 -1
  11. package/dist/api.js.map +1 -0
  12. package/dist/docs/index.d.ts +1 -0
  13. package/dist/docs/index.js +1 -1
  14. package/dist/docs/learning-journey-registry.docblock.d.ts +1 -0
  15. package/dist/docs/learning-journey-registry.docblock.js +38 -1
  16. package/dist/docs/learning-journey-registry.docblock.js.map +1 -0
  17. package/dist/example.d.ts +33 -0
  18. package/dist/example.d.ts.map +1 -0
  19. package/dist/example.js +35 -1
  20. package/dist/example.js.map +1 -0
  21. package/dist/index.d.ts +8 -0
  22. package/dist/index.js +10 -1
  23. package/dist/learning-journey-registry.feature.d.ts +12 -0
  24. package/dist/learning-journey-registry.feature.d.ts.map +1 -0
  25. package/dist/learning-journey-registry.feature.js +68 -1
  26. package/dist/learning-journey-registry.feature.js.map +1 -0
  27. package/dist/presentations/index.d.ts +10 -0
  28. package/dist/presentations/index.d.ts.map +1 -0
  29. package/dist/presentations/index.js +71 -1
  30. package/dist/presentations/index.js.map +1 -0
  31. package/dist/progress-store.d.ts +11 -0
  32. package/dist/progress-store.d.ts.map +1 -0
  33. package/dist/progress-store.js +31 -1
  34. package/dist/progress-store.js.map +1 -0
  35. package/dist/tracks.d.ts +40 -0
  36. package/dist/tracks.d.ts.map +1 -0
  37. package/dist/tracks.js +48 -1
  38. package/dist/tracks.js.map +1 -0
  39. package/dist/ui/LearningMiniApp.d.ts +24 -0
  40. package/dist/ui/LearningMiniApp.d.ts.map +1 -0
  41. package/dist/ui/LearningMiniApp.js +80 -1
  42. package/dist/ui/LearningMiniApp.js.map +1 -0
  43. package/dist/ui/index.d.ts +2 -0
  44. package/dist/ui/index.js +3 -1
  45. package/package.json +42 -30
  46. package/src/learning-journey-registry.feature.ts +7 -6
  47. package/src/presentations/index.ts +31 -23
  48. package/tsconfig.tsbuildinfo +1 -1
  49. package/tsdown.config.js +11 -1
  50. package/dist/libs/contracts/src/docs/PUBLISHING.docblock.js +0 -76
  51. package/dist/libs/contracts/src/docs/accessibility_wcag_compliance_specs.docblock.js +0 -350
  52. package/dist/libs/contracts/src/docs/index.js +0 -1
  53. package/dist/libs/contracts/src/docs/presentations.js +0 -1
  54. package/dist/libs/contracts/src/docs/registry.js +0 -1
  55. package/dist/libs/contracts/src/docs/tech/PHASE_1_QUICKSTART.docblock.js +0 -383
  56. package/dist/libs/contracts/src/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js +0 -68
  57. package/dist/libs/contracts/src/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js +0 -140
  58. package/dist/libs/contracts/src/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js +0 -86
  59. package/dist/libs/contracts/src/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js +0 -1
  60. package/dist/libs/contracts/src/docs/tech/auth/better-auth-nextjs.docblock.js +0 -58
  61. package/dist/libs/contracts/src/docs/tech/contracts/openapi-export.docblock.js +0 -38
  62. package/dist/libs/contracts/src/docs/tech/lifecycle-stage-system.docblock.js +0 -213
  63. package/dist/libs/contracts/src/docs/tech/llm/llm-integration.docblock.js +0 -289
  64. package/dist/libs/contracts/src/docs/tech/mcp-endpoints.docblock.js +0 -1
  65. package/dist/libs/contracts/src/docs/tech/presentation-runtime.docblock.js +0 -1
  66. package/dist/libs/contracts/src/docs/tech/schema/README.docblock.js +0 -262
  67. package/dist/libs/contracts/src/docs/tech/studio/learning-events.docblock.js +0 -1
  68. package/dist/libs/contracts/src/docs/tech/studio/learning-journeys.docblock.js +0 -57
  69. package/dist/libs/contracts/src/docs/tech/studio/platform-admin-panel.docblock.js +0 -63
  70. package/dist/libs/contracts/src/docs/tech/studio/project-access-teams.docblock.js +0 -36
  71. package/dist/libs/contracts/src/docs/tech/studio/project-routing.docblock.js +0 -1
  72. package/dist/libs/contracts/src/docs/tech/studio/sandbox-unlogged.docblock.js +0 -20
  73. package/dist/libs/contracts/src/docs/tech/studio/team-invitations.docblock.js +0 -65
  74. package/dist/libs/contracts/src/docs/tech/studio/workspace-ops.docblock.js +0 -1
  75. package/dist/libs/contracts/src/docs/tech/studio/workspaces.docblock.js +0 -41
  76. package/dist/libs/contracts/src/docs/tech/telemetry-ingest.docblock.js +0 -122
  77. package/dist/libs/contracts/src/docs/tech/templates/runtime.docblock.js +0 -1
  78. package/dist/libs/contracts/src/docs/tech/vscode-extension.docblock.js +0 -68
  79. package/dist/libs/contracts/src/docs/tech/workflows/overview.docblock.js +0 -1
@@ -0,0 +1,50 @@
1
+ $ tsdown
2
+ ℹ tsdown v0.18.3 powered by rolldown v1.0.0-beta.57
3
+ ℹ config file: /home/runner/work/contractspec/contractspec/packages/examples/learning-journey-registry/tsdown.config.js
4
+ ℹ entry: src/api-types.ts, src/api.ts, src/example.ts, src/index.ts, src/learning-journey-registry.feature.ts, src/progress-store.ts, src/tracks.ts, src/docs/index.ts, src/docs/learning-journey-registry.docblock.ts, src/presentations/index.ts, src/ui/LearningMiniApp.tsx, src/ui/index.ts
5
+ ℹ target: esnext
6
+ ℹ tsconfig: tsconfig.json
7
+ ℹ Build start
8
+ ℹ Cleaning 43 files
9
+ ℹ dist/api.js  6.79 kB │ gzip: 1.96 kB
10
+ ℹ dist/ui/LearningMiniApp.js  2.91 kB │ gzip: 0.98 kB
11
+ ℹ dist/tracks.js  1.76 kB │ gzip: 0.59 kB
12
+ ℹ dist/presentations/index.js  1.71 kB │ gzip: 0.59 kB
13
+ ℹ dist/learning-journey-registry.feature.js  1.36 kB │ gzip: 0.50 kB
14
+ ℹ dist/docs/learning-journey-registry.docblock.js  1.35 kB │ gzip: 0.70 kB
15
+ ℹ dist/index.js  1.14 kB │ gzip: 0.34 kB
16
+ ℹ dist/progress-store.js  0.84 kB │ gzip: 0.42 kB
17
+ ℹ dist/example.js  0.76 kB │ gzip: 0.41 kB
18
+ ℹ dist/ui/index.js  0.17 kB │ gzip: 0.09 kB
19
+ ℹ dist/docs/index.js  0.05 kB │ gzip: 0.07 kB
20
+ ℹ dist/api-types.js  0.00 kB │ gzip: 0.02 kB
21
+ ℹ dist/api.js.map 13.19 kB │ gzip: 3.84 kB
22
+ ℹ dist/ui/LearningMiniApp.js.map  5.04 kB │ gzip: 1.58 kB
23
+ ℹ dist/tracks.js.map  3.63 kB │ gzip: 1.09 kB
24
+ ℹ dist/presentations/index.js.map  2.94 kB │ gzip: 0.90 kB
25
+ ℹ dist/learning-journey-registry.feature.js.map  2.57 kB │ gzip: 0.95 kB
26
+ ℹ dist/docs/learning-journey-registry.docblock.js.map  1.75 kB │ gzip: 0.85 kB
27
+ ℹ dist/progress-store.js.map  1.66 kB │ gzip: 0.76 kB
28
+ ℹ dist/example.js.map  1.11 kB │ gzip: 0.58 kB
29
+ ℹ dist/api-types.d.ts.map  0.65 kB │ gzip: 0.34 kB
30
+ ℹ dist/tracks.d.ts.map  0.58 kB │ gzip: 0.30 kB
31
+ ℹ dist/ui/LearningMiniApp.d.ts.map  0.49 kB │ gzip: 0.29 kB
32
+ ℹ dist/progress-store.d.ts.map  0.34 kB │ gzip: 0.23 kB
33
+ ℹ dist/api.d.ts.map  0.26 kB │ gzip: 0.19 kB
34
+ ℹ dist/presentations/index.d.ts.map  0.23 kB │ gzip: 0.18 kB
35
+ ℹ dist/learning-journey-registry.feature.d.ts.map  0.18 kB │ gzip: 0.14 kB
36
+ ℹ dist/example.d.ts.map  0.14 kB │ gzip: 0.13 kB
37
+ ℹ dist/tracks.d.ts  1.73 kB │ gzip: 0.57 kB
38
+ ℹ dist/ui/LearningMiniApp.d.ts  1.20 kB │ gzip: 0.52 kB
39
+ ℹ dist/index.d.ts  1.17 kB │ gzip: 0.34 kB
40
+ ℹ dist/api-types.d.ts  1.07 kB │ gzip: 0.48 kB
41
+ ℹ dist/example.d.ts  0.99 kB │ gzip: 0.41 kB
42
+ ℹ dist/progress-store.d.ts  0.68 kB │ gzip: 0.30 kB
43
+ ℹ dist/presentations/index.d.ts  0.56 kB │ gzip: 0.22 kB
44
+ ℹ dist/api.d.ts  0.55 kB │ gzip: 0.29 kB
45
+ ℹ dist/learning-journey-registry.feature.d.ts  0.42 kB │ gzip: 0.24 kB
46
+ ℹ dist/ui/index.d.ts  0.17 kB │ gzip: 0.09 kB
47
+ ℹ dist/docs/index.d.ts  0.01 kB │ gzip: 0.03 kB
48
+ ℹ dist/docs/learning-journey-registry.docblock.d.ts  0.01 kB │ gzip: 0.03 kB
49
+ ℹ 40 files, total: 62.18 kB
50
+ ✔ Build complete in 3195ms
@@ -1,53 +1,51 @@
1
- $ bun build:bundle && bun build:types
1
+ $ bun build:types && bun build:bundle
2
+ $ tsc --noEmit
2
3
  $ tsdown
3
- ℹ tsdown v0.17.4 powered by rolldown v1.0.0-beta.53
4
+ ℹ tsdown v0.18.3 powered by rolldown v1.0.0-beta.57
4
5
  ℹ config file: /home/runner/work/contractspec/contractspec/packages/examples/learning-journey-registry/tsdown.config.js
5
6
  ℹ entry: src/api-types.ts, src/api.ts, src/example.ts, src/index.ts, src/learning-journey-registry.feature.ts, src/progress-store.ts, src/tracks.ts, src/docs/index.ts, src/docs/learning-journey-registry.docblock.ts, src/presentations/index.ts, src/ui/LearningMiniApp.tsx, src/ui/index.ts
6
7
  ℹ target: esnext
7
8
  ℹ tsconfig: tsconfig.json
8
9
  ℹ Build start
9
- ℹ dist/api.js  3.28 kB │ gzip: 1.37 kB
10
- ℹ dist/ui/LearningMiniApp.js  1.88 kB │ gzip: 0.70 kB
11
- ℹ dist/tracks.js  1.30 kB │ gzip: 0.50 kB
12
- ℹ dist/index.js  1.23 kB │ gzip: 0.42 kB
13
- ℹ dist/docs/learning-journey-registry.docblock.js  1.21 kB │ gzip: 0.63 kB
14
- ℹ dist/presentations/index.js  0.99 kB │ gzip: 0.39 kB
15
- ℹ dist/learning-journey-registry.feature.js  0.86 kB │ gzip: 0.36 kB
16
- ℹ dist/example.js  0.52 kB │ gzip: 0.32 kB
17
- ℹ dist/progress-store.js  0.43 kB │ gzip: 0.29 kB
18
- ℹ dist/ui/index.js  0.19 kB │ gzip: 0.11 kB
19
- ℹ dist/docs/index.js  0.05 kB │ gzip: 0.07 kB
20
- ℹ dist/api-types.js  0.00 kB │ gzip: 0.02 kB
21
- ℹ dist/libs/contracts/src/docs/accessibility_wcag_compliance_specs.docblock.js 16.53 kB │ gzip: 7.16 kB
22
- ℹ dist/libs/contracts/src/docs/tech/schema/README.docblock.js 10.99 kB │ gzip: 4.29 kB
23
- ℹ dist/libs/contracts/src/docs/tech/lifecycle-stage-system.docblock.js  9.67 kB │ gzip: 3.78 kB
24
- ℹ dist/libs/contracts/src/docs/tech/llm/llm-integration.docblock.js  9.12 kB │ gzip: 3.42 kB
25
- ℹ dist/libs/contracts/src/docs/tech/PHASE_1_QUICKSTART.docblock.js  8.76 kB │ gzip: 2.68 kB
26
- ℹ dist/libs/contracts/src/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js  5.93 kB │ gzip: 2.61 kB
27
- ℹ dist/libs/contracts/src/docs/tech/templates/runtime.docblock.js  5.63 kB │ gzip: 2.58 kB
28
- ℹ dist/libs/contracts/src/docs/tech/workflows/overview.docblock.js  5.44 kB │ gzip: 2.26 kB
29
- ℹ dist/libs/contracts/src/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js  4.37 kB │ gzip: 2.06 kB
30
- ℹ dist/libs/contracts/src/docs/tech/telemetry-ingest.docblock.js  3.90 kB │ gzip: 1.70 kB
31
- ℹ dist/libs/contracts/src/docs/tech/vscode-extension.docblock.js  3.60 kB │ gzip: 1.39 kB
32
- ℹ dist/libs/contracts/src/docs/PUBLISHING.docblock.js  3.43 kB │ gzip: 1.59 kB
33
- ℹ dist/libs/contracts/src/docs/tech/auth/better-auth-nextjs.docblock.js  3.35 kB │ gzip: 1.45 kB
34
- ℹ dist/libs/contracts/src/docs/tech/studio/learning-journeys.docblock.js  3.08 kB │ gzip: 1.39 kB
35
- ℹ dist/libs/contracts/src/docs/tech/studio/platform-admin-panel.docblock.js  3.04 kB │ gzip: 1.33 kB
36
- ℹ dist/libs/contracts/src/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js  3.00 kB │ gzip: 1.53 kB
37
- ℹ dist/libs/contracts/src/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js  2.83 kB │ gzip: 1.41 kB
38
- ℹ dist/libs/contracts/src/docs/tech/presentation-runtime.docblock.js  2.75 kB │ gzip: 1.30 kB
39
- ℹ dist/libs/contracts/src/docs/tech/studio/project-routing.docblock.js  2.50 kB │ gzip: 1.12 kB
40
- ℹ dist/libs/contracts/src/docs/tech/studio/team-invitations.docblock.js  2.14 kB │ gzip: 1.04 kB
41
- ℹ dist/libs/contracts/src/docs/tech/studio/workspaces.docblock.js  1.90 kB │ gzip: 0.94 kB
42
- ℹ dist/libs/contracts/src/docs/tech/studio/learning-events.docblock.js  1.79 kB │ gzip: 0.88 kB
43
- ℹ dist/libs/contracts/src/docs/tech/contracts/openapi-export.docblock.js  1.72 kB │ gzip: 0.90 kB
44
- ℹ dist/libs/contracts/src/docs/tech/studio/project-access-teams.docblock.js  1.58 kB │ gzip: 0.78 kB
45
- ℹ dist/libs/contracts/src/docs/index.js  1.54 kB │ gzip: 0.52 kB
46
- ℹ dist/libs/contracts/src/docs/tech/studio/workspace-ops.docblock.js  1.49 kB │ gzip: 0.73 kB
47
- ℹ dist/libs/contracts/src/docs/tech/mcp-endpoints.docblock.js  1.24 kB │ gzip: 0.68 kB
48
- ℹ dist/libs/contracts/src/docs/presentations.js  1.23 kB │ gzip: 0.59 kB
49
- ℹ dist/libs/contracts/src/docs/tech/studio/sandbox-unlogged.docblock.js  0.90 kB │ gzip: 0.56 kB
50
- ℹ dist/libs/contracts/src/docs/registry.js  0.74 kB │ gzip: 0.42 kB
51
- ℹ 42 files, total: 136.15 kB
52
- ✔ Build complete in 57ms
53
- $ tsc --noEmit
10
+ ℹ dist/api.js  6.79 kB │ gzip: 1.96 kB
11
+ ℹ dist/ui/LearningMiniApp.js  2.91 kB │ gzip: 0.98 kB
12
+ ℹ dist/tracks.js  1.76 kB │ gzip: 0.59 kB
13
+ ℹ dist/presentations/index.js  1.71 kB │ gzip: 0.59 kB
14
+ ℹ dist/learning-journey-registry.feature.js  1.36 kB │ gzip: 0.50 kB
15
+ ℹ dist/docs/learning-journey-registry.docblock.js  1.35 kB │ gzip: 0.70 kB
16
+ ℹ dist/index.js  1.14 kB │ gzip: 0.34 kB
17
+ ℹ dist/progress-store.js  0.84 kB │ gzip: 0.42 kB
18
+ ℹ dist/example.js  0.76 kB │ gzip: 0.41 kB
19
+ ℹ dist/ui/index.js  0.17 kB │ gzip: 0.09 kB
20
+ ℹ dist/docs/index.js  0.05 kB │ gzip: 0.07 kB
21
+ ℹ dist/api-types.js  0.00 kB │ gzip: 0.02 kB
22
+ ℹ dist/api.js.map 13.19 kB │ gzip: 3.84 kB
23
+ ℹ dist/ui/LearningMiniApp.js.map  5.04 kB │ gzip: 1.58 kB
24
+ ℹ dist/tracks.js.map  3.63 kB │ gzip: 1.09 kB
25
+ ℹ dist/presentations/index.js.map  2.94 kB │ gzip: 0.90 kB
26
+ ℹ dist/learning-journey-registry.feature.js.map  2.57 kB │ gzip: 0.95 kB
27
+ ℹ dist/docs/learning-journey-registry.docblock.js.map  1.75 kB │ gzip: 0.85 kB
28
+ ℹ dist/progress-store.js.map  1.66 kB │ gzip: 0.76 kB
29
+ ℹ dist/example.js.map  1.11 kB │ gzip: 0.58 kB
30
+ ℹ dist/api-types.d.ts.map  0.65 kB │ gzip: 0.34 kB
31
+ ℹ dist/tracks.d.ts.map  0.58 kB │ gzip: 0.30 kB
32
+ ℹ dist/ui/LearningMiniApp.d.ts.map  0.49 kB │ gzip: 0.29 kB
33
+ ℹ dist/progress-store.d.ts.map  0.34 kB │ gzip: 0.23 kB
34
+ ℹ dist/api.d.ts.map  0.26 kB │ gzip: 0.19 kB
35
+ ℹ dist/presentations/index.d.ts.map  0.23 kB │ gzip: 0.18 kB
36
+ ℹ dist/learning-journey-registry.feature.d.ts.map  0.18 kB │ gzip: 0.14 kB
37
+ ℹ dist/example.d.ts.map  0.14 kB │ gzip: 0.13 kB
38
+ ℹ dist/tracks.d.ts  1.73 kB │ gzip: 0.57 kB
39
+ ℹ dist/ui/LearningMiniApp.d.ts  1.20 kB │ gzip: 0.52 kB
40
+ ℹ dist/index.d.ts  1.17 kB │ gzip: 0.34 kB
41
+ ℹ dist/api-types.d.ts  1.07 kB │ gzip: 0.48 kB
42
+ ℹ dist/example.d.ts  0.99 kB │ gzip: 0.41 kB
43
+ ℹ dist/progress-store.d.ts  0.68 kB │ gzip: 0.30 kB
44
+ ℹ dist/presentations/index.d.ts  0.56 kB │ gzip: 0.22 kB
45
+ ℹ dist/api.d.ts  0.55 kB │ gzip: 0.29 kB
46
+ ℹ dist/learning-journey-registry.feature.d.ts  0.42 kB │ gzip: 0.24 kB
47
+ ℹ dist/ui/index.d.ts  0.17 kB │ gzip: 0.09 kB
48
+ ℹ dist/docs/index.d.ts  0.01 kB │ gzip: 0.03 kB
49
+ ℹ dist/docs/learning-journey-registry.docblock.d.ts  0.01 kB │ gzip: 0.03 kB
50
+ ℹ 40 files, total: 62.18 kB
51
+ ✔ Build complete in 3089ms
package/CHANGELOG.md ADDED
@@ -0,0 +1,64 @@
1
+ # @lssm/example.learning-journey-registry
2
+
3
+ ## 1.42.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 1f9ac4c: fix
8
+ - Updated dependencies [1f9ac4c]
9
+ - @lssm/example.learning-journey-ambient-coach@1.42.2
10
+ - @lssm/example.learning-journey-crm-onboarding@1.42.2
11
+ - @lssm/example.learning-journey-duo-drills@1.42.2
12
+ - @lssm/example.learning-journey-platform-tour@1.42.2
13
+ - @lssm/example.learning-journey-quest-challenges@1.42.2
14
+ - @lssm/example.learning-journey-studio-onboarding@1.42.2
15
+ - @lssm/example.learning-journey-ui-coaching@1.42.2
16
+ - @lssm/example.learning-journey-ui-gamified@1.42.2
17
+ - @lssm/example.learning-journey-ui-onboarding@1.42.2
18
+ - @lssm/example.learning-journey-ui-shared@1.42.2
19
+ - @lssm/lib.contracts@1.42.2
20
+ - @lssm/lib.schema@1.42.2
21
+ - @lssm/module.learning-journey@1.42.2
22
+
23
+ ## 1.42.1
24
+
25
+ ### Patch Changes
26
+
27
+ - f043995: Fix release
28
+ - Updated dependencies [f043995]
29
+ - @lssm/example.learning-journey-studio-onboarding@1.42.1
30
+ - @lssm/example.learning-journey-quest-challenges@1.42.1
31
+ - @lssm/example.learning-journey-crm-onboarding@1.42.1
32
+ - @lssm/example.learning-journey-ambient-coach@1.42.1
33
+ - @lssm/example.learning-journey-platform-tour@1.42.1
34
+ - @lssm/example.learning-journey-ui-onboarding@1.42.1
35
+ - @lssm/example.learning-journey-ui-coaching@1.42.1
36
+ - @lssm/example.learning-journey-ui-gamified@1.42.1
37
+ - @lssm/example.learning-journey-duo-drills@1.42.1
38
+ - @lssm/example.learning-journey-ui-shared@1.42.1
39
+ - @lssm/module.learning-journey@1.42.1
40
+ - @lssm/lib.contracts@1.42.1
41
+ - @lssm/lib.schema@1.42.1
42
+
43
+ ## 1.42.0
44
+
45
+ ### Minor Changes
46
+
47
+ - 8eefd9c: initial release
48
+
49
+ ### Patch Changes
50
+
51
+ - Updated dependencies [8eefd9c]
52
+ - @lssm/example.learning-journey-ambient-coach@1.42.0
53
+ - @lssm/example.learning-journey-crm-onboarding@1.42.0
54
+ - @lssm/example.learning-journey-duo-drills@1.42.0
55
+ - @lssm/example.learning-journey-platform-tour@1.42.0
56
+ - @lssm/example.learning-journey-quest-challenges@1.42.0
57
+ - @lssm/example.learning-journey-studio-onboarding@1.42.0
58
+ - @lssm/example.learning-journey-ui-coaching@1.42.0
59
+ - @lssm/example.learning-journey-ui-gamified@1.42.0
60
+ - @lssm/example.learning-journey-ui-onboarding@1.42.0
61
+ - @lssm/example.learning-journey-ui-shared@1.42.0
62
+ - @lssm/lib.contracts@1.42.0
63
+ - @lssm/lib.schema@1.42.0
64
+ - @lssm/module.learning-journey@1.42.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Chaman Ventures, SASU
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # @lssm/example.learning-journey-registry
2
2
 
3
+ Website: https://contractspec.lssm.tech/
4
+
5
+
3
6
  Aggregated registry for learning journey example tracks.
4
7
 
5
8
  ## Contents
@@ -0,0 +1,41 @@
1
+ import { LearningJourneyTrackSpec } from "@lssm/module.learning-journey/track-spec";
2
+
3
+ //#region src/api-types.d.ts
4
+ interface LearningEvent {
5
+ name: string;
6
+ version?: number;
7
+ sourceModule?: string;
8
+ payload?: Record<string, unknown>;
9
+ occurredAt?: Date;
10
+ learnerId: string;
11
+ trackId?: string;
12
+ }
13
+ type StepStatus = 'PENDING' | 'COMPLETED';
14
+ interface StepProgress {
15
+ id: string;
16
+ status: StepStatus;
17
+ xpEarned: number;
18
+ completedAt?: Date;
19
+ triggeringEvent?: string;
20
+ eventPayload?: Record<string, unknown>;
21
+ occurrences?: number;
22
+ counterStartedAt?: Date;
23
+ availableAt?: Date;
24
+ dueAt?: Date;
25
+ masteryCount?: number;
26
+ }
27
+ interface TrackProgress {
28
+ learnerId: string;
29
+ trackId: string;
30
+ progress: number;
31
+ isCompleted: boolean;
32
+ xpEarned: number;
33
+ startedAt?: Date;
34
+ completedAt?: Date;
35
+ lastActivityAt?: Date;
36
+ steps: StepProgress[];
37
+ }
38
+ type TrackResolver = (trackId: string) => LearningJourneyTrackSpec | undefined;
39
+ //#endregion
40
+ export { LearningEvent, StepProgress, StepStatus, TrackProgress, TrackResolver };
41
+ //# sourceMappingURL=api-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-types.d.ts","names":[],"sources":["../src/api-types.ts"],"sourcesContent":[],"mappings":";;;UAEiB,aAAA;;EAAA,OAAA,CAAA,EAAA,MAAa;EAUlB,YAAA,CAAU,EAAA,MAAA;EAEL,OAAA,CAAA,EARL,MAQiB,CAAA,MAAA,EAAA,OAAA,CAAA;EAEnB,UAAA,CAAA,EATK,IASL;EAEM,SAAA,EAAA,MAAA;EAEC,OAAA,CAAA,EAAA,MAAA;;AAGD,KAXJ,UAAA,GAWI,SAAA,GAAA,WAAA;AACN,UAVO,YAAA,CAUP;EAAI,EAAA,EAAA,MAAA;EAIG,MAAA,EAZP,UAYoB;EAMhB,QAAA,EAAA,MAAA;EACE,WAAA,CAAA,EAjBA,IAiBA;EACG,eAAA,CAAA,EAAA,MAAA;EACV,YAAA,CAAA,EAjBQ,MAiBR,CAAA,MAAA,EAAA,OAAA,CAAA;EAAY,WAAA,CAAA,EAAA,MAAA;EAGT,gBAAa,CAAA,EAlBJ,IAkBI;gBAjBT;UACN;;;UAIO,aAAA;;;;;;cAMH;gBACE;mBACG;SACV;;KAGG,aAAA,wBAEP"}
package/dist/api.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { LearningEvent, TrackProgress } from "./api-types.js";
2
+ import { LearningJourneyTrackSpec } from "@lssm/module.learning-journey/track-spec";
3
+
4
+ //#region src/api.d.ts
5
+ declare const listTracks: (learnerId?: string) => {
6
+ tracks: LearningJourneyTrackSpec[];
7
+ progress: TrackProgress[];
8
+ };
9
+ declare const getProgress: (trackId: string, learnerId: string) => TrackProgress | undefined;
10
+ declare const recordEvent: (event: LearningEvent) => TrackProgress[];
11
+ //#endregion
12
+ export { getProgress, listTracks, recordEvent };
13
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","names":[],"sources":["../src/api.ts"],"sourcesContent":[],"mappings":";;;;cAyLa;UAWZ;EAXY,QAAA,EAWZ,aAAA,EAAA;AAED,CAAA;AAUa,cAVA,WAUsB,EAAA,CAAA,OAAA,EAAA,MAAa,EAAA,SAAA,EAAA,MAAA,EAAA,GAVc,aAUd,GAAA,SAAA;cAAnC,qBAAsB,kBAAa"}
package/dist/api.js CHANGED
@@ -1 +1,171 @@
1
- import{learningJourneyTracks as e}from"./tracks.js";import{getLearnerTracks as t,getTrackResolver as n,initProgress as r}from"./progress-store.js";const i=n(e),a=(e,t)=>e?t?Object.entries(e).every(([e,n])=>t[e]===n):!1:!0,o=(e,t)=>e.eventName!==t.name||e.eventVersion!==void 0&&t.version!==void 0&&e.eventVersion!==t.version||e.sourceModule&&t.sourceModule&&e.sourceModule!==t.sourceModule?!1:a(e.payloadFilter,t.payload),s=(e,t,n,r)=>{if(e.kind===`count`){if(!o(e,t))return{matched:!1};let i=(n.occurrences??0)+1;return{matched:(e.withinHours===void 0||!!(r&&t.occurredAt&&(t.occurredAt.getTime()-r.getTime())/(1e3*60*60)<=e.withinHours))&&i>=e.atLeast,occurrences:i}}if(e.kind===`time_window`)return!o(e,t)||e.withinHoursOfStart!==void 0&&r&&t.occurredAt&&(t.occurredAt.getTime()-r.getTime())/(1e3*60*60)>e.withinHoursOfStart?{matched:!1}:{matched:!0};if(e.kind===`srs_mastery`){if(t.name!==e.eventName)return{matched:!1};let r=t.payload;if(!a(e.payloadFilter,r))return{matched:!1};let i=e.skillIdField??`skillId`,o=e.masteryField??`mastery`,s=r?.[i],c=r?.[o];if(s===void 0||c===void 0||typeof c!=`number`||c<e.minimumMastery)return{matched:!1};let l=(n.masteryCount??0)+1;return{matched:l>=(e.requiredCount??1),masteryCount:l}}return{matched:o(e,t)}},c=(e,t)=>{if(!e||!t)return{};let n=t.getTime(),r=n;e.unlockOnDay!==void 0&&(r=n+(e.unlockOnDay-1)*24*60*60*1e3),e.unlockAfterHours!==void 0&&(r=n+e.unlockAfterHours*60*60*1e3);let i=new Date(r);return{availableAt:i,dueAt:e.dueWithinHours===void 0?void 0:new Date(i.getTime()+e.dueWithinHours*60*60*1e3)}},l=e=>{let t=e.length||1,n=e.filter(e=>e.status===`COMPLETED`).length;return Math.round(n/t*100)},u=(e,t)=>{if(t.isCompleted)return t;let n=new Date,r=t.startedAt??n,i=(n.getTime()-r.getTime())/(1e3*60*60),a=t.xpEarned,{completionRewards:o,streakRule:s}=e;return o?.xpBonus&&(a+=o.xpBonus),s?.hoursWindow!==void 0&&i<=s.hoursWindow&&s.bonusXp&&(a+=s.bonusXp),{...t,xpEarned:a,isCompleted:!0,completedAt:n,lastActivityAt:n}},d=n=>{let r=n?t(n):void 0;return{tracks:e,progress:n&&r?Array.from(r.values()):[]}},f=(e,n)=>{let a=i(e);if(!a)return;let o=t(n),s=o.get(e)??r(n,a);return o.set(e,s),s},p=n=>{let i=n.trackId===void 0?e:e.filter(e=>e.id===n.trackId),a=[],o=n.occurredAt??new Date;for(let e of i){let i=t(n.learnerId),d=i.get(e.id)??r(n.learnerId,e),f=d.startedAt??o,p=d.startedAt===void 0,m=d.steps.map(t=>{if(t.status===`COMPLETED`)return t;let r=e.steps.find(e=>e.id===t.id);if(!r)return t;let{availableAt:i,dueAt:a}=c(r.availability,f);if(i&&o<i||a&&o>a)return{...t,availableAt:i,dueAt:a};let l=s(r.completion,n,t,f);return l.matched?(p=!0,{...t,status:`COMPLETED`,xpEarned:r.xpReward??0,completedAt:o,triggeringEvent:n.name,eventPayload:n.payload,occurrences:l.occurrences??t.occurrences,masteryCount:l.masteryCount??t.masteryCount,availableAt:i,dueAt:a}):((l.occurrences!==void 0||l.masteryCount!==void 0)&&(p=!0),{...t,occurrences:l.occurrences??t.occurrences,masteryCount:l.masteryCount??t.masteryCount,availableAt:i,dueAt:a})});if(!p)continue;let h=m.reduce((e,t)=>e+t.xpEarned,0)+(e.totalXp??0),g={...d,steps:m,xpEarned:h,startedAt:f,lastActivityAt:o,progress:l(m)};m.every(e=>e.status===`COMPLETED`)&&(g=u(e,g)),i.set(e.id,g),a.push(g)}return a};export{f as getProgress,d as listTracks,p as recordEvent};
1
+ import { learningJourneyTracks } from "./tracks.js";
2
+ import { getLearnerTracks, getTrackResolver, initProgress } from "./progress-store.js";
3
+
4
+ //#region src/api.ts
5
+ const getTrack = getTrackResolver(learningJourneyTracks);
6
+ const matchesFilter = (filter, payload) => {
7
+ if (!filter) return true;
8
+ if (!payload) return false;
9
+ return Object.entries(filter).every(([key, value]) => payload[key] === value);
10
+ };
11
+ const matchesBaseEvent = (condition, event) => {
12
+ if (condition.eventName !== event.name) return false;
13
+ if (condition.eventVersion !== void 0 && event.version !== void 0) {
14
+ if (condition.eventVersion !== event.version) return false;
15
+ }
16
+ if (condition.sourceModule && event.sourceModule && condition.sourceModule !== event.sourceModule) return false;
17
+ return matchesFilter(condition.payloadFilter, event.payload);
18
+ };
19
+ const matchesCondition = (condition, event, step, trackStartedAt) => {
20
+ if (condition.kind === "count") {
21
+ if (!matchesBaseEvent(condition, event)) return { matched: false };
22
+ const occurrences = (step.occurrences ?? 0) + 1;
23
+ return {
24
+ matched: (condition.withinHours === void 0 || Boolean(trackStartedAt && event.occurredAt && (event.occurredAt.getTime() - trackStartedAt.getTime()) / (1e3 * 60 * 60) <= condition.withinHours)) && occurrences >= condition.atLeast,
25
+ occurrences
26
+ };
27
+ }
28
+ if (condition.kind === "time_window") {
29
+ if (!matchesBaseEvent(condition, event)) return { matched: false };
30
+ if (condition.withinHoursOfStart !== void 0 && trackStartedAt && event.occurredAt) {
31
+ if ((event.occurredAt.getTime() - trackStartedAt.getTime()) / (1e3 * 60 * 60) > condition.withinHoursOfStart) return { matched: false };
32
+ }
33
+ return { matched: true };
34
+ }
35
+ if (condition.kind === "srs_mastery") {
36
+ if (event.name !== condition.eventName) return { matched: false };
37
+ const payload = event.payload;
38
+ if (!matchesFilter(condition.payloadFilter, payload)) return { matched: false };
39
+ const skillKey = condition.skillIdField ?? "skillId";
40
+ const masteryKey = condition.masteryField ?? "mastery";
41
+ const skillId = payload?.[skillKey];
42
+ const masteryValue = payload?.[masteryKey];
43
+ if (skillId === void 0 || masteryValue === void 0) return { matched: false };
44
+ if (typeof masteryValue !== "number") return { matched: false };
45
+ if (masteryValue < condition.minimumMastery) return { matched: false };
46
+ const masteryCount = (step.masteryCount ?? 0) + 1;
47
+ return {
48
+ matched: masteryCount >= (condition.requiredCount ?? 1),
49
+ masteryCount
50
+ };
51
+ }
52
+ return { matched: matchesBaseEvent(condition, event) };
53
+ };
54
+ const getAvailability = (availability, startedAt) => {
55
+ if (!availability || !startedAt) return {};
56
+ const baseTime = startedAt.getTime();
57
+ let unlockTime = baseTime;
58
+ if (availability.unlockOnDay !== void 0) unlockTime = baseTime + (availability.unlockOnDay - 1) * 24 * 60 * 60 * 1e3;
59
+ if (availability.unlockAfterHours !== void 0) unlockTime = baseTime + availability.unlockAfterHours * 60 * 60 * 1e3;
60
+ const availableAt = new Date(unlockTime);
61
+ return {
62
+ availableAt,
63
+ dueAt: availability.dueWithinHours !== void 0 ? new Date(availableAt.getTime() + availability.dueWithinHours * 60 * 60 * 1e3) : void 0
64
+ };
65
+ };
66
+ const computeProgressPercent = (steps) => {
67
+ const total = steps.length || 1;
68
+ const done = steps.filter((s) => s.status === "COMPLETED").length;
69
+ return Math.round(done / total * 100);
70
+ };
71
+ const applyTrackCompletionBonuses = (track, progress) => {
72
+ if (progress.isCompleted) return progress;
73
+ const completedAt = /* @__PURE__ */ new Date();
74
+ const startedAt = progress.startedAt ?? completedAt;
75
+ const hoursElapsed = (completedAt.getTime() - startedAt.getTime()) / (1e3 * 60 * 60);
76
+ let xpEarned = progress.xpEarned;
77
+ const { completionRewards, streakRule } = track;
78
+ if (completionRewards?.xpBonus) xpEarned += completionRewards.xpBonus;
79
+ if (streakRule?.hoursWindow !== void 0 && hoursElapsed <= streakRule.hoursWindow && streakRule.bonusXp) xpEarned += streakRule.bonusXp;
80
+ return {
81
+ ...progress,
82
+ xpEarned,
83
+ isCompleted: true,
84
+ completedAt,
85
+ lastActivityAt: completedAt
86
+ };
87
+ };
88
+ const listTracks = (learnerId) => {
89
+ const progressMap = learnerId ? getLearnerTracks(learnerId) : void 0;
90
+ return {
91
+ tracks: learningJourneyTracks,
92
+ progress: learnerId && progressMap ? Array.from(progressMap.values()) : []
93
+ };
94
+ };
95
+ const getProgress = (trackId, learnerId) => {
96
+ const track = getTrack(trackId);
97
+ if (!track) return void 0;
98
+ const map = getLearnerTracks(learnerId);
99
+ const existing = map.get(trackId) ?? initProgress(learnerId, track);
100
+ map.set(trackId, existing);
101
+ return existing;
102
+ };
103
+ const recordEvent = (event) => {
104
+ const targets = event.trackId !== void 0 ? learningJourneyTracks.filter((t) => t.id === event.trackId) : learningJourneyTracks;
105
+ const updated = [];
106
+ const eventTime = event.occurredAt ?? /* @__PURE__ */ new Date();
107
+ for (const track of targets) {
108
+ const map = getLearnerTracks(event.learnerId);
109
+ const current = map.get(track.id) ?? initProgress(event.learnerId, track);
110
+ const startedAt = current.startedAt ?? eventTime;
111
+ let changed = current.startedAt === void 0;
112
+ const steps = current.steps.map((step) => {
113
+ if (step.status === "COMPLETED") return step;
114
+ const spec = track.steps.find((s) => s.id === step.id);
115
+ if (!spec) return step;
116
+ const { availableAt, dueAt } = getAvailability(spec.availability, startedAt);
117
+ if (availableAt && eventTime < availableAt) return {
118
+ ...step,
119
+ availableAt,
120
+ dueAt
121
+ };
122
+ if (dueAt && eventTime > dueAt) return {
123
+ ...step,
124
+ availableAt,
125
+ dueAt
126
+ };
127
+ const result = matchesCondition(spec.completion, event, step, startedAt);
128
+ if (result.matched) {
129
+ changed = true;
130
+ return {
131
+ ...step,
132
+ status: "COMPLETED",
133
+ xpEarned: spec.xpReward ?? 0,
134
+ completedAt: eventTime,
135
+ triggeringEvent: event.name,
136
+ eventPayload: event.payload,
137
+ occurrences: result.occurrences ?? step.occurrences,
138
+ masteryCount: result.masteryCount ?? step.masteryCount,
139
+ availableAt,
140
+ dueAt
141
+ };
142
+ }
143
+ if (result.occurrences !== void 0 || result.masteryCount !== void 0) changed = true;
144
+ return {
145
+ ...step,
146
+ occurrences: result.occurrences ?? step.occurrences,
147
+ masteryCount: result.masteryCount ?? step.masteryCount,
148
+ availableAt,
149
+ dueAt
150
+ };
151
+ });
152
+ if (!changed) continue;
153
+ const xpEarned = steps.reduce((sum, s) => sum + s.xpEarned, 0) + (track.totalXp ?? 0);
154
+ let progress = {
155
+ ...current,
156
+ steps,
157
+ xpEarned,
158
+ startedAt,
159
+ lastActivityAt: eventTime,
160
+ progress: computeProgressPercent(steps)
161
+ };
162
+ if (steps.every((s) => s.status === "COMPLETED")) progress = applyTrackCompletionBonuses(track, progress);
163
+ map.set(track.id, progress);
164
+ updated.push(progress);
165
+ }
166
+ return updated;
167
+ };
168
+
169
+ //#endregion
170
+ export { getProgress, listTracks, recordEvent };
171
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","names":["updated: TrackProgress[]","steps: StepProgress[]","progress: TrackProgress"],"sources":["../src/api.ts"],"sourcesContent":["import { learningJourneyTracks } from './tracks';\nimport type {\n LearningJourneyTrackSpec,\n StepAvailabilitySpec,\n StepCompletionConditionSpec,\n} from '@lssm/module.learning-journey/track-spec';\nimport type { LearningEvent, StepProgress, TrackProgress } from './api-types';\nimport {\n getLearnerTracks,\n getTrackResolver,\n initProgress,\n} from './progress-store';\n\nconst getTrack = getTrackResolver(learningJourneyTracks);\n\nconst matchesFilter = (\n filter: Record<string, unknown> | undefined,\n payload: Record<string, unknown> | undefined\n): boolean => {\n if (!filter) return true;\n if (!payload) return false;\n return Object.entries(filter).every(([key, value]) => payload[key] === value);\n};\n\nconst matchesBaseEvent = (\n condition: {\n eventName: string;\n eventVersion?: number;\n sourceModule?: string;\n payloadFilter?: Record<string, unknown>;\n },\n event: LearningEvent\n): boolean => {\n if (condition.eventName !== event.name) return false;\n if (condition.eventVersion !== undefined && event.version !== undefined) {\n if (condition.eventVersion !== event.version) return false;\n }\n if (\n condition.sourceModule &&\n event.sourceModule &&\n condition.sourceModule !== event.sourceModule\n ) {\n return false;\n }\n return matchesFilter(\n condition.payloadFilter,\n event.payload as Record<string, unknown> | undefined\n );\n};\n\nconst matchesCondition = (\n condition: StepCompletionConditionSpec,\n event: LearningEvent,\n step: StepProgress,\n trackStartedAt: Date | undefined\n): {\n matched: boolean;\n occurrences?: number;\n masteryCount?: number;\n} => {\n if (condition.kind === 'count') {\n if (!matchesBaseEvent(condition, event)) return { matched: false };\n const occurrences = (step.occurrences ?? 0) + 1;\n const within =\n condition.withinHours === undefined ||\n Boolean(\n trackStartedAt &&\n event.occurredAt &&\n (event.occurredAt.getTime() - trackStartedAt.getTime()) /\n (1000 * 60 * 60) <=\n condition.withinHours\n );\n return { matched: within && occurrences >= condition.atLeast, occurrences };\n }\n\n if (condition.kind === 'time_window') {\n if (!matchesBaseEvent(condition, event)) return { matched: false };\n if (\n condition.withinHoursOfStart !== undefined &&\n trackStartedAt &&\n event.occurredAt\n ) {\n const hoursSinceStart =\n (event.occurredAt.getTime() - trackStartedAt.getTime()) /\n (1000 * 60 * 60);\n if (hoursSinceStart > condition.withinHoursOfStart) {\n return { matched: false };\n }\n }\n return { matched: true };\n }\n\n if (condition.kind === 'srs_mastery') {\n if (event.name !== condition.eventName) return { matched: false };\n const payload = event.payload as Record<string, unknown> | undefined;\n if (!matchesFilter(condition.payloadFilter, payload)) {\n return { matched: false };\n }\n const skillKey = condition.skillIdField ?? 'skillId';\n const masteryKey = condition.masteryField ?? 'mastery';\n const skillId = payload?.[skillKey];\n const masteryValue = payload?.[masteryKey];\n if (skillId === undefined || masteryValue === undefined) {\n return { matched: false };\n }\n if (typeof masteryValue !== 'number') return { matched: false };\n if (masteryValue < condition.minimumMastery) return { matched: false };\n const masteryCount = (step.masteryCount ?? 0) + 1;\n const required = condition.requiredCount ?? 1;\n return { matched: masteryCount >= required, masteryCount };\n }\n\n return { matched: matchesBaseEvent(condition, event) };\n};\n\nconst getAvailability = (\n availability: StepAvailabilitySpec | undefined,\n startedAt: Date | undefined\n): { availableAt?: Date; dueAt?: Date } => {\n if (!availability || !startedAt) return {};\n\n const baseTime = startedAt.getTime();\n let unlockTime = baseTime;\n\n if (availability.unlockOnDay !== undefined) {\n unlockTime =\n baseTime + (availability.unlockOnDay - 1) * 24 * 60 * 60 * 1000;\n }\n\n if (availability.unlockAfterHours !== undefined) {\n unlockTime = baseTime + availability.unlockAfterHours * 60 * 60 * 1000;\n }\n\n const availableAt = new Date(unlockTime);\n const dueAt =\n availability.dueWithinHours !== undefined\n ? new Date(\n availableAt.getTime() + availability.dueWithinHours * 60 * 60 * 1000\n )\n : undefined;\n\n return { availableAt, dueAt };\n};\n\nconst computeProgressPercent = (steps: StepProgress[]): number => {\n const total = steps.length || 1;\n const done = steps.filter((s) => s.status === 'COMPLETED').length;\n return Math.round((done / total) * 100);\n};\n\nconst applyTrackCompletionBonuses = (\n track: LearningJourneyTrackSpec,\n progress: TrackProgress\n) => {\n if (progress.isCompleted) return progress;\n\n const completedAt = new Date();\n const startedAt = progress.startedAt ?? completedAt;\n const hoursElapsed =\n (completedAt.getTime() - startedAt.getTime()) / (1000 * 60 * 60);\n\n let xpEarned = progress.xpEarned;\n const { completionRewards, streakRule } = track;\n\n if (completionRewards?.xpBonus) {\n xpEarned += completionRewards.xpBonus;\n }\n\n if (\n streakRule?.hoursWindow !== undefined &&\n hoursElapsed <= streakRule.hoursWindow &&\n streakRule.bonusXp\n ) {\n xpEarned += streakRule.bonusXp;\n }\n\n return {\n ...progress,\n xpEarned,\n isCompleted: true,\n completedAt,\n lastActivityAt: completedAt,\n };\n};\n\nexport const listTracks = (learnerId?: string) => {\n const progressMap = learnerId ? getLearnerTracks(learnerId) : undefined;\n const progress =\n learnerId && progressMap\n ? Array.from(progressMap.values())\n : ([] as TrackProgress[]);\n\n return {\n tracks: learningJourneyTracks,\n progress,\n };\n};\n\nexport const getProgress = (trackId: string, learnerId: string) => {\n const track = getTrack(trackId);\n if (!track) return undefined;\n\n const map = getLearnerTracks(learnerId);\n const existing = map.get(trackId) ?? initProgress(learnerId, track);\n map.set(trackId, existing);\n return existing;\n};\n\nexport const recordEvent = (event: LearningEvent) => {\n const targets =\n event.trackId !== undefined\n ? learningJourneyTracks.filter((t) => t.id === event.trackId)\n : learningJourneyTracks;\n\n const updated: TrackProgress[] = [];\n const eventTime = event.occurredAt ?? new Date();\n\n for (const track of targets) {\n const map = getLearnerTracks(event.learnerId);\n const current = map.get(track.id) ?? initProgress(event.learnerId, track);\n const startedAt = current.startedAt ?? eventTime;\n\n let changed = current.startedAt === undefined;\n const steps: StepProgress[] = current.steps.map((step) => {\n if (step.status === 'COMPLETED') return step;\n\n const spec = track.steps.find((s) => s.id === step.id);\n if (!spec) return step;\n\n const { availableAt, dueAt } = getAvailability(\n spec.availability,\n startedAt\n );\n if (availableAt && eventTime < availableAt) {\n return { ...step, availableAt, dueAt };\n }\n if (dueAt && eventTime > dueAt) {\n // keep pending but note deadlines\n return { ...step, availableAt, dueAt };\n }\n\n const result = matchesCondition(spec.completion, event, step, startedAt);\n\n if (result.matched) {\n changed = true;\n return {\n ...step,\n status: 'COMPLETED',\n xpEarned: spec.xpReward ?? 0,\n completedAt: eventTime,\n triggeringEvent: event.name,\n eventPayload: event.payload,\n occurrences: result.occurrences ?? step.occurrences,\n masteryCount: result.masteryCount ?? step.masteryCount,\n availableAt,\n dueAt,\n };\n }\n\n if (\n result.occurrences !== undefined ||\n result.masteryCount !== undefined\n ) {\n changed = true;\n }\n\n return {\n ...step,\n occurrences: result.occurrences ?? step.occurrences,\n masteryCount: result.masteryCount ?? step.masteryCount,\n availableAt,\n dueAt,\n };\n });\n\n if (!changed) {\n continue;\n }\n\n const xpEarned =\n steps.reduce((sum, s) => sum + s.xpEarned, 0) + (track.totalXp ?? 0);\n let progress: TrackProgress = {\n ...current,\n steps,\n xpEarned,\n startedAt,\n lastActivityAt: eventTime,\n progress: computeProgressPercent(steps),\n };\n\n const allDone = steps.every((s) => s.status === 'COMPLETED');\n if (allDone) {\n progress = applyTrackCompletionBonuses(track, progress);\n }\n\n map.set(track.id, progress);\n updated.push(progress);\n }\n\n return updated;\n};\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { };
@@ -1 +1 @@
1
- import"./learning-journey-registry.docblock.js";
1
+ import "./learning-journey-registry.docblock.js";
@@ -0,0 +1 @@
1
+ export { };
@@ -1 +1,38 @@
1
- import{registerDocBlocks as e}from"../libs/contracts/src/docs/registry.js";import"../libs/contracts/src/docs/index.js";e([{id:`docs.learning-journey.registry`,title:`Learning Journey — Example Track Registry`,summary:`Aggregates learning journey example tracks (Studio onboarding, Platform tour, CRM first win, Drills, Ambient Coach, Quest challenges).`,kind:`usage`,visibility:`public`,route:`/docs/learning-journey/registry`,tags:[`learning`,`registry`,`onboarding`],body:"## Tracks\n- `studio_getting_started` (Studio onboarding)\n- `platform_primitives_tour` (Platform primitives)\n- `crm_first_win` (CRM pipeline onboarding)\n- `drills_language_basics` (Drills & SRS)\n- `money_ambient_coach`, `coliving_ambient_coach` (Ambient tips)\n- `money_reset_7day` (Quest/challenge)\n\n## Exports\n- `learningJourneyTracks` — raw specs\n- `onboardingTrackCatalog` — DTOs aligned with onboarding API\n- `mapTrackSpecToDto` — helper to map individual tracks\n\n## Wiring\n- Use with onboarding API contracts:\n - `learning.onboarding.listTracks`\n - `learning.onboarding.getProgress`\n - `learning.onboarding.recordEvent`\n- Intended for registry/adapters in Studio UI or services that surface tracks."}]);
1
+ import { registerDocBlocks } from "@lssm/lib.contracts/docs";
2
+
3
+ //#region src/docs/learning-journey-registry.docblock.ts
4
+ registerDocBlocks([{
5
+ id: "docs.learning-journey.registry",
6
+ title: "Learning Journey — Example Track Registry",
7
+ summary: "Aggregates learning journey example tracks (Studio onboarding, Platform tour, CRM first win, Drills, Ambient Coach, Quest challenges).",
8
+ kind: "usage",
9
+ visibility: "public",
10
+ route: "/docs/learning-journey/registry",
11
+ tags: [
12
+ "learning",
13
+ "registry",
14
+ "onboarding"
15
+ ],
16
+ body: `## Tracks
17
+ - \`studio_getting_started\` (Studio onboarding)
18
+ - \`platform_primitives_tour\` (Platform primitives)
19
+ - \`crm_first_win\` (CRM pipeline onboarding)
20
+ - \`drills_language_basics\` (Drills & SRS)
21
+ - \`money_ambient_coach\`, \`coliving_ambient_coach\` (Ambient tips)
22
+ - \`money_reset_7day\` (Quest/challenge)
23
+
24
+ ## Exports
25
+ - \`learningJourneyTracks\` — raw specs
26
+ - \`onboardingTrackCatalog\` — DTOs aligned with onboarding API
27
+ - \`mapTrackSpecToDto\` — helper to map individual tracks
28
+
29
+ ## Wiring
30
+ - Use with onboarding API contracts:
31
+ - \`learning.onboarding.listTracks\`
32
+ - \`learning.onboarding.getProgress\`
33
+ - \`learning.onboarding.recordEvent\`
34
+ - Intended for registry/adapters in Studio UI or services that surface tracks.`
35
+ }]);
36
+
37
+ //#endregion
38
+ //# sourceMappingURL=learning-journey-registry.docblock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learning-journey-registry.docblock.js","names":[],"sources":["../../src/docs/learning-journey-registry.docblock.ts"],"sourcesContent":["import type { DocBlock } from '@lssm/lib.contracts/docs';\nimport { registerDocBlocks } from '@lssm/lib.contracts/docs';\n\nconst registryDocBlocks: DocBlock[] = [\n {\n id: 'docs.learning-journey.registry',\n title: 'Learning Journey — Example Track Registry',\n summary:\n 'Aggregates learning journey example tracks (Studio onboarding, Platform tour, CRM first win, Drills, Ambient Coach, Quest challenges).',\n kind: 'usage',\n visibility: 'public',\n route: '/docs/learning-journey/registry',\n tags: ['learning', 'registry', 'onboarding'],\n body: `## Tracks\n- \\`studio_getting_started\\` (Studio onboarding)\n- \\`platform_primitives_tour\\` (Platform primitives)\n- \\`crm_first_win\\` (CRM pipeline onboarding)\n- \\`drills_language_basics\\` (Drills & SRS)\n- \\`money_ambient_coach\\`, \\`coliving_ambient_coach\\` (Ambient tips)\n- \\`money_reset_7day\\` (Quest/challenge)\n\n## Exports\n- \\`learningJourneyTracks\\` — raw specs\n- \\`onboardingTrackCatalog\\` — DTOs aligned with onboarding API\n- \\`mapTrackSpecToDto\\` — helper to map individual tracks\n\n## Wiring\n- Use with onboarding API contracts:\n - \\`learning.onboarding.listTracks\\`\n - \\`learning.onboarding.getProgress\\`\n - \\`learning.onboarding.recordEvent\\`\n- Intended for registry/adapters in Studio UI or services that surface tracks.`,\n },\n];\n\nregisterDocBlocks(registryDocBlocks);\n"],"mappings":";;;AAmCA,kBAhCsC,CACpC;CACE,IAAI;CACJ,OAAO;CACP,SACE;CACF,MAAM;CACN,YAAY;CACZ,OAAO;CACP,MAAM;EAAC;EAAY;EAAY;EAAa;CAC5C,MAAM;;;;;;;;;;;;;;;;;;;CAmBP,CACF,CAEmC"}