qlm-measure 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +54 -0
- package/NOTICE +13 -0
- package/README.md +152 -0
- package/dist/clients/engine-client.d.ts +51 -0
- package/dist/clients/engine-client.d.ts.map +1 -0
- package/dist/clients/engine-client.js +59 -0
- package/dist/clients/engine-client.js.map +1 -0
- package/dist/clients/index.d.ts +5 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +3 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/ontology-client.d.ts +57 -0
- package/dist/clients/ontology-client.d.ts.map +1 -0
- package/dist/clients/ontology-client.js +47 -0
- package/dist/clients/ontology-client.js.map +1 -0
- package/dist/emitter/index.d.ts +3 -0
- package/dist/emitter/index.d.ts.map +1 -0
- package/dist/emitter/index.js +2 -0
- package/dist/emitter/index.js.map +1 -0
- package/dist/emitter/measurement-emitter.d.ts +33 -0
- package/dist/emitter/measurement-emitter.d.ts.map +1 -0
- package/dist/emitter/measurement-emitter.js +98 -0
- package/dist/emitter/measurement-emitter.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/schema/enums.d.ts +19 -0
- package/dist/schema/enums.d.ts.map +1 -0
- package/dist/schema/enums.js +24 -0
- package/dist/schema/enums.js.map +1 -0
- package/dist/schema/evidence-record.d.ts +70 -0
- package/dist/schema/evidence-record.d.ts.map +1 -0
- package/dist/schema/evidence-record.js +11 -0
- package/dist/schema/evidence-record.js.map +1 -0
- package/dist/schema/index.d.ts +7 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/measurement-event.d.ts +35 -0
- package/dist/schema/measurement-event.d.ts.map +1 -0
- package/dist/schema/measurement-event.js +7 -0
- package/dist/schema/measurement-event.js.map +1 -0
- package/dist/schema/observation-event.d.ts +58 -0
- package/dist/schema/observation-event.d.ts.map +1 -0
- package/dist/schema/observation-event.js +12 -0
- package/dist/schema/observation-event.js.map +1 -0
- package/dist/verifier/hash.d.ts +28 -0
- package/dist/verifier/hash.d.ts.map +1 -0
- package/dist/verifier/hash.js +75 -0
- package/dist/verifier/hash.js.map +1 -0
- package/dist/verifier/index.d.ts +5 -0
- package/dist/verifier/index.d.ts.map +1 -0
- package/dist/verifier/index.js +4 -0
- package/dist/verifier/index.js.map +1 -0
- package/dist/verifier/replay.d.ts +34 -0
- package/dist/verifier/replay.d.ts.map +1 -0
- package/dist/verifier/replay.js +51 -0
- package/dist/verifier/replay.js.map +1 -0
- package/dist/verifier/verify-record.d.ts +48 -0
- package/dist/verifier/verify-record.d.ts.map +1 -0
- package/dist/verifier/verify-record.js +163 -0
- package/dist/verifier/verify-record.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
9
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
10
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
11
|
+
the copyright owner that is granting the License.
|
|
12
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
13
|
+
other entities that control, are controlled by, or are under common
|
|
14
|
+
control with that entity.
|
|
15
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
16
|
+
exercising permissions granted by this License.
|
|
17
|
+
"Source" form shall mean the preferred form for making modifications.
|
|
18
|
+
"Object" form shall mean any form resulting from mechanical
|
|
19
|
+
transformation or translation of a Source form.
|
|
20
|
+
"Work" shall mean the work of authorship made available under the License.
|
|
21
|
+
"Derivative Works" shall mean any work that is based on the Work.
|
|
22
|
+
"Contribution" shall mean any work of authorship submitted to the
|
|
23
|
+
Licensor for inclusion in the Work.
|
|
24
|
+
"Contributor" shall mean Licensor and any Legal Entity on behalf of
|
|
25
|
+
whom a Contribution has been received by the Licensor.
|
|
26
|
+
|
|
27
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
28
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
29
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
30
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
31
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
32
|
+
Work and such Derivative Works in Source or Object form.
|
|
33
|
+
|
|
34
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
35
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
36
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
37
|
+
patent license to make, have made, use, offer to sell, sell, import,
|
|
38
|
+
and otherwise transfer the Work.
|
|
39
|
+
|
|
40
|
+
4-9. [Standard Apache 2.0 terms apply]
|
|
41
|
+
|
|
42
|
+
Copyright 2026 Quantum Learning Machines
|
|
43
|
+
|
|
44
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
45
|
+
you may not use this file except in compliance with the License.
|
|
46
|
+
You may obtain a copy of the License at
|
|
47
|
+
|
|
48
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
49
|
+
|
|
50
|
+
Unless required by applicable law or agreed to in writing, software
|
|
51
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
52
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
53
|
+
See the License for the specific language governing permissions and
|
|
54
|
+
limitations under the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
qlm-measure
|
|
2
|
+
Copyright 2026 Quantum Learning Machines
|
|
3
|
+
|
|
4
|
+
This product includes software developed at
|
|
5
|
+
Quantum Learning Machines (https://quantumlearningmachines.com).
|
|
6
|
+
|
|
7
|
+
This SDK provides the public interface layer for the QLM measurement
|
|
8
|
+
infrastructure. The estimation engine (Bayesian posteriors, IRT ability
|
|
9
|
+
estimation, calibration, and cognitive dimension tracking) is a separate
|
|
10
|
+
hosted service operated by Quantum Learning Machines.
|
|
11
|
+
|
|
12
|
+
The SDK itself (event schema, emitter, verifier, and dataset clients)
|
|
13
|
+
is licensed under the Apache License, Version 2.0.
|
package/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# @qlm/measure
|
|
2
|
+
|
|
3
|
+
Open measurement SDK for education AI — evidence events, record verification, and dataset clients.
|
|
4
|
+
|
|
5
|
+
**v0.1.0 · Apache-2.0 · [Documentation](https://play.quantumlearningmachines.com/developer) · [Manifesto](https://play.quantumlearningmachines.com/resources/open-measurement-layer)**
|
|
6
|
+
|
|
7
|
+
## Limitations (read first)
|
|
8
|
+
|
|
9
|
+
- This SDK is the **public interface layer**, not the measurement engine. The estimation service (Bayesian posteriors, IRT ability estimation, calibration) is QLM's hosted engine.
|
|
10
|
+
- The verifier checks **bookkeeping integrity**, not estimation correctness. It can tell you if a record was tampered with. It cannot tell you if the posteriors are accurate. That distinction is the design.
|
|
11
|
+
- Evidence event schemas are **v0.1** and may change in minor versions. Pin your dependency.
|
|
12
|
+
- The ontology client requires the QLM API to be reachable. No offline mode.
|
|
13
|
+
- Classifier runners require model weights downloaded separately from Hugging Face.
|
|
14
|
+
|
|
15
|
+
## What it is
|
|
16
|
+
|
|
17
|
+
1. **Typed evidence-event vocabulary** (`ObservationEvent`) — a schema any tool can emit to describe a student interaction, with scaffold level, depth, epistemic mode.
|
|
18
|
+
2. **Buffered telemetry emitter** (`MeasurementEmitter`) — sends events to the measurement service with sendBeacon fallback.
|
|
19
|
+
3. **Evidence record format + replay verifier** (`verifyRecord`, `replayToVersion`) — audits a record's hash-chain and posterior-chain integrity without containing any estimation mathematics.
|
|
20
|
+
4. **Dataset clients** (`OntologyClient`) — typed wrappers over the public misconception ontology, learning graph, and standards alignment APIs.
|
|
21
|
+
5. **Engine client** (`EngineClient`) — commercial boundary for the hosted measurement service.
|
|
22
|
+
|
|
23
|
+
## What it is NOT
|
|
24
|
+
|
|
25
|
+
- Not the estimation engine (that runs server-side at QLM)
|
|
26
|
+
- Not a standalone learning analytics system
|
|
27
|
+
- Not a replacement for the measurement service
|
|
28
|
+
- Not a classifier or scorer (those are separate open-weights releases)
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @qlm/measure
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quickstart
|
|
37
|
+
|
|
38
|
+
### 1. Query the misconception ontology (no auth)
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { OntologyClient } from "@qlm/measure/clients";
|
|
42
|
+
|
|
43
|
+
const client = new OntologyClient();
|
|
44
|
+
const misconceptions = await client.getMisconceptions("math");
|
|
45
|
+
console.log(`${misconceptions.length} math misconceptions`);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2. Emit measurement events
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { MeasurementEmitter } from "@qlm/measure/emitter";
|
|
52
|
+
|
|
53
|
+
const emitter = new MeasurementEmitter({
|
|
54
|
+
baseUrl: "https://play.quantumlearningmachines.com",
|
|
55
|
+
product: "my-tool",
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
emitter.emit({
|
|
59
|
+
eventType: "answer_submitted",
|
|
60
|
+
eventCategory: "learning",
|
|
61
|
+
domain: "math",
|
|
62
|
+
topic: "fractions",
|
|
63
|
+
payload: { questionId: "q1", correct: true },
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 3. Verify an evidence record (tamper detection)
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { verifyRecord } from "@qlm/measure/verifier";
|
|
71
|
+
|
|
72
|
+
const result = verifyRecord(record);
|
|
73
|
+
if (!result.valid) {
|
|
74
|
+
for (const v of result.violations) {
|
|
75
|
+
console.log(`[${v.category}] v${v.version}: ${v.message}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Schema Reference
|
|
81
|
+
|
|
82
|
+
### ObservationEvent (evidence input)
|
|
83
|
+
|
|
84
|
+
| Field | Type | Required | Description |
|
|
85
|
+
|-------|------|----------|-------------|
|
|
86
|
+
| studentId | string | yes | Pseudonymous ID (no PII) |
|
|
87
|
+
| sessionId | string | yes | Session identifier |
|
|
88
|
+
| source | string | yes | Source system |
|
|
89
|
+
| timestamp | string | yes | ISO 8601 |
|
|
90
|
+
| correct | boolean | yes | Was the response correct? |
|
|
91
|
+
| responseTimeMs | number | yes | Response time in ms |
|
|
92
|
+
| domain | string | yes | Subject domain |
|
|
93
|
+
| scaffoldType | ScaffoldType | no | What preceded this response |
|
|
94
|
+
| misconceptionId | string | no | Detected misconception ID |
|
|
95
|
+
| classifierConfidence | number | no | Classifier confidence (0-1) |
|
|
96
|
+
| skillId | string | no | Skill being assessed |
|
|
97
|
+
| score | number | no | Response score (0-1) |
|
|
98
|
+
| difficulty | number | no | Item difficulty (0-1) |
|
|
99
|
+
| epistemicMode | EpistemicMode | no | How student arrived at answer |
|
|
100
|
+
| ext | Record | no | Extension namespace |
|
|
101
|
+
|
|
102
|
+
### Enums
|
|
103
|
+
|
|
104
|
+
**ScaffoldType:** `none`, `socratic`, `probing`, `metacognitive`, `scaffolding`, `explain`, `hint`, `demonstrate`
|
|
105
|
+
|
|
106
|
+
**EpistemicMode:** `experience`, `inference`, `analogy`, `testimony`
|
|
107
|
+
|
|
108
|
+
**DepthLevel:** `surface`, `conceptual`, `transfer`, `integration`
|
|
109
|
+
|
|
110
|
+
**TriageResult:** `correct`, `slip`, `misconception`, `disengagement`, `ambiguous`
|
|
111
|
+
|
|
112
|
+
## Verifier
|
|
113
|
+
|
|
114
|
+
The verifier checks:
|
|
115
|
+
- Schema validity (required fields, correct types)
|
|
116
|
+
- Strictly monotonic version numbers
|
|
117
|
+
- Timestamp monotonicity (configurable tolerance)
|
|
118
|
+
- Hash-chain integrity (prevHash linkage, entryHash recompute)
|
|
119
|
+
- Posterior chain consistency (each prior = previous updated)
|
|
120
|
+
- Compaction-boundary integrity
|
|
121
|
+
- Enum validity
|
|
122
|
+
|
|
123
|
+
What it deliberately **cannot** check:
|
|
124
|
+
- Whether posteriors are correctly computed (that requires the engine)
|
|
125
|
+
- Whether evidential weights are appropriate (those are calibrated server-side)
|
|
126
|
+
- Whether triage classifications are accurate (those use rules not in this package)
|
|
127
|
+
|
|
128
|
+
This is the design: **verify instead of trust**.
|
|
129
|
+
|
|
130
|
+
## Privacy
|
|
131
|
+
|
|
132
|
+
- `studentId` MUST be a pseudonymous identifier. Never include names, emails, or other PII.
|
|
133
|
+
- Events are buffered locally and sent via sendBeacon/fetch. No cookies are set.
|
|
134
|
+
- The SDK does not store any data persistently.
|
|
135
|
+
|
|
136
|
+
## Versioning
|
|
137
|
+
|
|
138
|
+
- Semver from 0.1.0.
|
|
139
|
+
- Schema changes in minor versions (0.2, 0.3).
|
|
140
|
+
- Breaking changes in major versions (1.0).
|
|
141
|
+
- Pin your dependency version.
|
|
142
|
+
|
|
143
|
+
## Links
|
|
144
|
+
|
|
145
|
+
- [Developer portal](https://play.quantumlearningmachines.com/developer)
|
|
146
|
+
- [Open Measurement Manifesto](https://play.quantumlearningmachines.com/resources/open-measurement-layer)
|
|
147
|
+
- [Misconception ontology](https://play.quantumlearningmachines.com/developer)
|
|
148
|
+
- [Model cards on Hugging Face](https://huggingface.co/QuantumLearningMachines)
|
|
149
|
+
|
|
150
|
+
## License
|
|
151
|
+
|
|
152
|
+
Apache-2.0. See [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EngineClient — Commercial boundary for the QLM measurement engine.
|
|
3
|
+
*
|
|
4
|
+
* The estimation service is QLM's hosted engine. This client wraps the
|
|
5
|
+
* API for submitting observations and retrieving student model state.
|
|
6
|
+
*
|
|
7
|
+
* Authentication is required. Contact QLM for API access.
|
|
8
|
+
*/
|
|
9
|
+
import type { ObservationEvent } from "../schema/observation-event";
|
|
10
|
+
export interface EngineClientConfig {
|
|
11
|
+
/** Base URL of the QLM measurement service. */
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
/** API key for authentication. */
|
|
14
|
+
apiKey: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ModelStateSummary {
|
|
17
|
+
studentId: string;
|
|
18
|
+
totalSessions: number;
|
|
19
|
+
totalEvidenceEvents: number;
|
|
20
|
+
lastSessionAt: string | null;
|
|
21
|
+
/** Top misconceptions with posterior > 0.3 */
|
|
22
|
+
activeMisconceptions: Array<{
|
|
23
|
+
id: string;
|
|
24
|
+
posterior: number;
|
|
25
|
+
persistence: string;
|
|
26
|
+
detections: number;
|
|
27
|
+
}>;
|
|
28
|
+
/** Triage summary */
|
|
29
|
+
triage: {
|
|
30
|
+
correct: number;
|
|
31
|
+
slips: number;
|
|
32
|
+
misconceptions: number;
|
|
33
|
+
disengagements: number;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export declare class EngineClient {
|
|
37
|
+
private readonly config;
|
|
38
|
+
constructor(config: EngineClientConfig);
|
|
39
|
+
/**
|
|
40
|
+
* Submit a student observation to the measurement engine.
|
|
41
|
+
*
|
|
42
|
+
* The engine runs the full measurement pipeline and returns
|
|
43
|
+
* a summary of the updated state.
|
|
44
|
+
*/
|
|
45
|
+
updateStudentModel(observation: ObservationEvent): Promise<ModelStateSummary>;
|
|
46
|
+
/**
|
|
47
|
+
* Retrieve the current model state for a student.
|
|
48
|
+
*/
|
|
49
|
+
getState(studentId: string): Promise<ModelStateSummary>;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=engine-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-client.d.ts","sourceRoot":"","sources":["../../src/clients/engine-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,MAAM,WAAW,kBAAkB;IACjC,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,8CAA8C;IAC9C,oBAAoB,EAAE,KAAK,CAAC;QAC1B,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,qBAAqB;IACrB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;gBAEhC,MAAM,EAAE,kBAAkB;IAItC;;;;;OAKG;IACG,kBAAkB,CAAC,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA0BnF;;OAEG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAiB9D"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EngineClient — Commercial boundary for the QLM measurement engine.
|
|
3
|
+
*
|
|
4
|
+
* The estimation service is QLM's hosted engine. This client wraps the
|
|
5
|
+
* API for submitting observations and retrieving student model state.
|
|
6
|
+
*
|
|
7
|
+
* Authentication is required. Contact QLM for API access.
|
|
8
|
+
*/
|
|
9
|
+
import { toPublicEpistemicMode } from "../schema/enums";
|
|
10
|
+
export class EngineClient {
|
|
11
|
+
config;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Submit a student observation to the measurement engine.
|
|
17
|
+
*
|
|
18
|
+
* The engine runs the full measurement pipeline and returns
|
|
19
|
+
* a summary of the updated state.
|
|
20
|
+
*/
|
|
21
|
+
async updateStudentModel(observation) {
|
|
22
|
+
// Map public epistemic mode to internal at the boundary
|
|
23
|
+
const mapped = {
|
|
24
|
+
...observation,
|
|
25
|
+
epistemicMode: observation.epistemicMode
|
|
26
|
+
? toPublicEpistemicMode(observation.epistemicMode)
|
|
27
|
+
: undefined,
|
|
28
|
+
};
|
|
29
|
+
const response = await fetch(`${this.config.baseUrl}/api/student-model/update`, {
|
|
30
|
+
method: "POST",
|
|
31
|
+
headers: {
|
|
32
|
+
"Content-Type": "application/json",
|
|
33
|
+
"Authorization": `Bearer ${this.config.apiKey}`,
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify(mapped),
|
|
36
|
+
});
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
const body = await response.text().catch(() => "");
|
|
39
|
+
throw new Error(`EngineClient.updateStudentModel: ${response.status} ${response.statusText} — ${body}`);
|
|
40
|
+
}
|
|
41
|
+
return response.json();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Retrieve the current model state for a student.
|
|
45
|
+
*/
|
|
46
|
+
async getState(studentId) {
|
|
47
|
+
const response = await fetch(`${this.config.baseUrl}/api/student-model/state?studentId=${encodeURIComponent(studentId)}`, {
|
|
48
|
+
headers: {
|
|
49
|
+
"Authorization": `Bearer ${this.config.apiKey}`,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
const body = await response.text().catch(() => "");
|
|
54
|
+
throw new Error(`EngineClient.getState: ${response.status} ${response.statusText} — ${body}`);
|
|
55
|
+
}
|
|
56
|
+
return response.json();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=engine-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-client.js","sourceRoot":"","sources":["../../src/clients/engine-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA8BxD,MAAM,OAAO,YAAY;IACN,MAAM,CAAqB;IAE5C,YAAY,MAA0B;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,kBAAkB,CAAC,WAA6B;QACpD,wDAAwD;QACxD,MAAM,MAAM,GAAG;YACb,GAAG,WAAW;YACd,aAAa,EAAE,WAAW,CAAC,aAAa;gBACtC,CAAC,CAAC,qBAAqB,CAAC,WAAW,CAAC,aAAa,CAAC;gBAClD,CAAC,CAAC,SAAS;SACd,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,2BAA2B,EAAE;YAC9E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;aAChD;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SAC7B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,oCAAoC,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,MAAM,IAAI,EAAE,CAAC,CAAC;QAC1G,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,SAAiB;QAC9B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,sCAAsC,kBAAkB,CAAC,SAAS,CAAC,EAAE,EAC3F;YACE,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;aAChD;SACF,CACF,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,MAAM,IAAI,EAAE,CAAC,CAAC;QAChG,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgC,CAAC;IACvD,CAAC;CACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { OntologyClient } from "./ontology-client";
|
|
2
|
+
export type { OntologyClientConfig, DatasetName, MisconceptionEntry, LearningGraphNode, StandardAlignment } from "./ontology-client";
|
|
3
|
+
export { EngineClient } from "./engine-client";
|
|
4
|
+
export type { EngineClientConfig, ModelStateSummary } from "./engine-client";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/clients/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrI,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/clients/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OntologyClient — Typed wrapper over the QLM dataset export API.
|
|
3
|
+
*
|
|
4
|
+
* Zero-auth. Queries the public misconception ontology, learning graph,
|
|
5
|
+
* and standards alignment datasets.
|
|
6
|
+
*/
|
|
7
|
+
export type DatasetName = "misconceptions" | "learning-graph" | "standards" | "assistments-alignment";
|
|
8
|
+
export interface OntologyClientConfig {
|
|
9
|
+
/** Base URL of the QLM API. Default: https://play.quantumlearningmachines.com */
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface MisconceptionEntry {
|
|
13
|
+
id: string;
|
|
14
|
+
domain: string;
|
|
15
|
+
topic: string;
|
|
16
|
+
label: string;
|
|
17
|
+
description: string;
|
|
18
|
+
triggerPatterns: string[];
|
|
19
|
+
correctivePrompts: string[];
|
|
20
|
+
gradeRange?: string;
|
|
21
|
+
severity?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface LearningGraphNode {
|
|
24
|
+
id: string;
|
|
25
|
+
label: string;
|
|
26
|
+
domain: string;
|
|
27
|
+
prerequisites: string[];
|
|
28
|
+
relatedMisconceptions: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface StandardAlignment {
|
|
31
|
+
standardCode: string;
|
|
32
|
+
framework: string;
|
|
33
|
+
description: string;
|
|
34
|
+
mappedConstructIds: string[];
|
|
35
|
+
}
|
|
36
|
+
export declare class OntologyClient {
|
|
37
|
+
private readonly baseUrl;
|
|
38
|
+
constructor(config?: OntologyClientConfig);
|
|
39
|
+
/**
|
|
40
|
+
* Fetch a dataset from the public export API.
|
|
41
|
+
*
|
|
42
|
+
* @param dataset The dataset name to fetch.
|
|
43
|
+
* @param options Optional query parameters (domain, format).
|
|
44
|
+
* @returns Parsed JSON response.
|
|
45
|
+
*/
|
|
46
|
+
fetchDataset<T = unknown>(dataset: DatasetName, options?: {
|
|
47
|
+
domain?: string;
|
|
48
|
+
format?: string;
|
|
49
|
+
}): Promise<T>;
|
|
50
|
+
/** Fetch the misconception ontology. */
|
|
51
|
+
getMisconceptions(domain?: string): Promise<MisconceptionEntry[]>;
|
|
52
|
+
/** Fetch the learning graph. */
|
|
53
|
+
getLearningGraph(domain?: string): Promise<LearningGraphNode[]>;
|
|
54
|
+
/** Fetch standards alignment data. */
|
|
55
|
+
getStandards(domain?: string): Promise<StandardAlignment[]>;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=ontology-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ontology-client.d.ts","sourceRoot":"","sources":["../../src/clients/ontology-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,WAAW,GACnB,gBAAgB,GAChB,gBAAgB,GAChB,WAAW,GACX,uBAAuB,CAAC;AAE5B,MAAM,WAAW,oBAAoB;IACnC,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,CAAC,EAAE,oBAAoB;IAIzC;;;;;;OAMG;IACG,YAAY,CAAC,CAAC,GAAG,OAAO,EAC5B,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC7C,OAAO,CAAC,CAAC,CAAC;IAiBb,wCAAwC;IAClC,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAIvE,gCAAgC;IAC1B,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIrE,sCAAsC;IAChC,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAGlE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OntologyClient — Typed wrapper over the QLM dataset export API.
|
|
3
|
+
*
|
|
4
|
+
* Zero-auth. Queries the public misconception ontology, learning graph,
|
|
5
|
+
* and standards alignment datasets.
|
|
6
|
+
*/
|
|
7
|
+
export class OntologyClient {
|
|
8
|
+
baseUrl;
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.baseUrl = config?.baseUrl ?? "https://play.quantumlearningmachines.com";
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Fetch a dataset from the public export API.
|
|
14
|
+
*
|
|
15
|
+
* @param dataset The dataset name to fetch.
|
|
16
|
+
* @param options Optional query parameters (domain, format).
|
|
17
|
+
* @returns Parsed JSON response.
|
|
18
|
+
*/
|
|
19
|
+
async fetchDataset(dataset, options) {
|
|
20
|
+
const params = new URLSearchParams({ dataset });
|
|
21
|
+
if (options?.domain)
|
|
22
|
+
params.set("domain", options.domain);
|
|
23
|
+
if (options?.format)
|
|
24
|
+
params.set("format", options.format);
|
|
25
|
+
const url = `${this.baseUrl}/api/labpath/dataset-export?${params.toString()}`;
|
|
26
|
+
const response = await fetch(url, {
|
|
27
|
+
headers: { Accept: "application/json" },
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
throw new Error(`OntologyClient: ${response.status} ${response.statusText} for ${dataset}`);
|
|
31
|
+
}
|
|
32
|
+
return response.json();
|
|
33
|
+
}
|
|
34
|
+
/** Fetch the misconception ontology. */
|
|
35
|
+
async getMisconceptions(domain) {
|
|
36
|
+
return this.fetchDataset("misconceptions", { domain });
|
|
37
|
+
}
|
|
38
|
+
/** Fetch the learning graph. */
|
|
39
|
+
async getLearningGraph(domain) {
|
|
40
|
+
return this.fetchDataset("learning-graph", { domain });
|
|
41
|
+
}
|
|
42
|
+
/** Fetch standards alignment data. */
|
|
43
|
+
async getStandards(domain) {
|
|
44
|
+
return this.fetchDataset("standards", { domain });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=ontology-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ontology-client.js","sourceRoot":"","sources":["../../src/clients/ontology-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwCH,MAAM,OAAO,cAAc;IACR,OAAO,CAAS;IAEjC,YAAY,MAA6B;QACvC,IAAI,CAAC,OAAO,GAAG,MAAM,EAAE,OAAO,IAAI,0CAA0C,CAAC;IAC/E,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,YAAY,CAChB,OAAoB,EACpB,OAA8C;QAE9C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,IAAI,OAAO,EAAE,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1D,IAAI,OAAO,EAAE,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAE1D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,+BAA+B,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC9E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;SACxC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,QAAQ,OAAO,EAAE,CAAC,CAAC;QAC9F,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;IACvC,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,iBAAiB,CAAC,MAAe;QACrC,OAAO,IAAI,CAAC,YAAY,CAAuB,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,gCAAgC;IAChC,KAAK,CAAC,gBAAgB,CAAC,MAAe;QACpC,OAAO,IAAI,CAAC,YAAY,CAAsB,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,sCAAsC;IACtC,KAAK,CAAC,YAAY,CAAC,MAAe;QAChC,OAAO,IAAI,CAAC,YAAY,CAAsB,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emitter/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/emitter/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Measurement Emitter — Buffered telemetry for the open measurement layer.
|
|
3
|
+
*
|
|
4
|
+
* Buffers events and flushes via sendBeacon (browser) or fetch (Node).
|
|
5
|
+
* Survives page unload. Configurable endpoint and buffer size.
|
|
6
|
+
*/
|
|
7
|
+
import type { MeasurementEvent } from "../schema/measurement-event";
|
|
8
|
+
export interface EmitterConfig {
|
|
9
|
+
/** Base URL of the measurement service. */
|
|
10
|
+
baseUrl: string;
|
|
11
|
+
/** API key for authentication (optional for public endpoints). */
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
/** Product identifier. */
|
|
14
|
+
product?: string;
|
|
15
|
+
/** Maximum events to buffer before auto-flush. Default: 20. */
|
|
16
|
+
bufferSize?: number;
|
|
17
|
+
/** Flush interval in milliseconds. Default: 5000. */
|
|
18
|
+
flushIntervalMs?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class MeasurementEmitter {
|
|
21
|
+
private buffer;
|
|
22
|
+
private timer;
|
|
23
|
+
private readonly config;
|
|
24
|
+
private readonly ingestUrl;
|
|
25
|
+
constructor(config: EmitterConfig);
|
|
26
|
+
/** Emit a measurement event. Buffered until flush. */
|
|
27
|
+
emit(event: MeasurementEvent): void;
|
|
28
|
+
/** Flush all buffered events to the measurement service. */
|
|
29
|
+
flush(): void;
|
|
30
|
+
/** Stop the auto-flush timer. */
|
|
31
|
+
destroy(): void;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=measurement-emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measurement-emitter.d.ts","sourceRoot":"","sources":["../../src/emitter/measurement-emitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAEpE,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAWD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,MAAM,EAAE,aAAa;IAmBjC,sDAAsD;IACtD,IAAI,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAgBnC,4DAA4D;IAC5D,KAAK,IAAI,IAAI;IA2Cb,iCAAiC;IACjC,OAAO,IAAI,IAAI;CAOhB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Measurement Emitter — Buffered telemetry for the open measurement layer.
|
|
3
|
+
*
|
|
4
|
+
* Buffers events and flushes via sendBeacon (browser) or fetch (Node).
|
|
5
|
+
* Survives page unload. Configurable endpoint and buffer size.
|
|
6
|
+
*/
|
|
7
|
+
function generateEventId(product) {
|
|
8
|
+
return `${product}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
9
|
+
}
|
|
10
|
+
export class MeasurementEmitter {
|
|
11
|
+
buffer = [];
|
|
12
|
+
timer = null;
|
|
13
|
+
config;
|
|
14
|
+
ingestUrl;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = {
|
|
17
|
+
baseUrl: config.baseUrl,
|
|
18
|
+
apiKey: config.apiKey ?? "",
|
|
19
|
+
product: config.product ?? "external",
|
|
20
|
+
bufferSize: config.bufferSize ?? 20,
|
|
21
|
+
flushIntervalMs: config.flushIntervalMs ?? 5000,
|
|
22
|
+
};
|
|
23
|
+
this.ingestUrl = `${this.config.baseUrl}/api/measurement/ingest`;
|
|
24
|
+
// Auto-flush on page visibility change (browser only)
|
|
25
|
+
if (typeof window !== "undefined") {
|
|
26
|
+
window.addEventListener("visibilitychange", () => {
|
|
27
|
+
if (document.visibilityState === "hidden")
|
|
28
|
+
this.flush();
|
|
29
|
+
});
|
|
30
|
+
window.addEventListener("pagehide", () => this.flush());
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Emit a measurement event. Buffered until flush. */
|
|
34
|
+
emit(event) {
|
|
35
|
+
this.buffer.push({
|
|
36
|
+
...event,
|
|
37
|
+
event_id: generateEventId(this.config.product),
|
|
38
|
+
created_at: new Date().toISOString(),
|
|
39
|
+
});
|
|
40
|
+
if (this.buffer.length >= this.config.bufferSize) {
|
|
41
|
+
this.flush();
|
|
42
|
+
}
|
|
43
|
+
if (!this.timer) {
|
|
44
|
+
this.timer = setInterval(() => this.flush(), this.config.flushIntervalMs);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Flush all buffered events to the measurement service. */
|
|
48
|
+
flush() {
|
|
49
|
+
if (this.buffer.length === 0)
|
|
50
|
+
return;
|
|
51
|
+
const batch = this.buffer.splice(0);
|
|
52
|
+
const body = JSON.stringify({
|
|
53
|
+
product: this.config.product,
|
|
54
|
+
events: batch.map((e) => ({
|
|
55
|
+
event_id: e.event_id,
|
|
56
|
+
event_type: e.eventType,
|
|
57
|
+
event_category: e.eventCategory,
|
|
58
|
+
session_id: e.sessionId ?? null,
|
|
59
|
+
classroom_id: e.classroomId ?? null,
|
|
60
|
+
domain: e.domain ?? null,
|
|
61
|
+
topic: e.topic ?? null,
|
|
62
|
+
mode: e.mode ?? null,
|
|
63
|
+
difficulty: e.difficulty ?? null,
|
|
64
|
+
payload: e.payload ?? {},
|
|
65
|
+
quality_signal: e.qualitySignal ?? null,
|
|
66
|
+
confidence: e.confidence ?? null,
|
|
67
|
+
duration_ms: e.durationMs ?? null,
|
|
68
|
+
parent_event_id: e.parentEventId ?? null,
|
|
69
|
+
created_at: e.created_at,
|
|
70
|
+
})),
|
|
71
|
+
});
|
|
72
|
+
const headers = { "Content-Type": "application/json" };
|
|
73
|
+
if (this.config.apiKey) {
|
|
74
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
75
|
+
}
|
|
76
|
+
// sendBeacon in browser (survives page unload)
|
|
77
|
+
if (typeof navigator !== "undefined" && navigator.sendBeacon) {
|
|
78
|
+
navigator.sendBeacon(this.ingestUrl, new Blob([body], { type: "application/json" }));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
fetch(this.ingestUrl, {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers,
|
|
84
|
+
body,
|
|
85
|
+
keepalive: true,
|
|
86
|
+
}).catch(() => { });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Stop the auto-flush timer. */
|
|
90
|
+
destroy() {
|
|
91
|
+
if (this.timer) {
|
|
92
|
+
clearInterval(this.timer);
|
|
93
|
+
this.timer = null;
|
|
94
|
+
}
|
|
95
|
+
this.flush();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=measurement-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measurement-emitter.js","sourceRoot":"","sources":["../../src/emitter/measurement-emitter.ts"],"names":[],"mappings":"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"}
|