@quran-lab/tajweedformer 2.0.0 → 2.0.1

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.
@@ -4,7 +4,7 @@
4
4
  // signed, valid 7 days); POST /v1/uploads/{id}/urls?from=n answers the next batch, or fresh URLs for
5
5
  // the same numbers. Segments go straight to R2 as plain PUTs. Nothing is sent at the end.
6
6
 
7
- export const SDK_VERSION = '2.0.0';
7
+ export const SDK_VERSION = '2.0.1';
8
8
  export const INPUT_ROUTES = Object.freeze(['built_in', 'wired', 'usb', 'bluetooth', 'car', 'continuity', 'other', 'unknown']);
9
9
  const CONSENT_RE = /^[A-Za-z0-9._-]{1,32}$/;
10
10
  const DEVICE_RE = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,23}$/;
@@ -14,9 +14,10 @@ const HEX64 = /^[0-9a-f]{64}$/;
14
14
  /** "2026-11-07": the UTC day. */
15
15
  export const utcDay = (ms = Date.now()) => new Date(ms).toISOString().slice(0, 10);
16
16
 
17
- /** The session JSON sent at the start: exactly the fields of qlab-api's closed schema. */
17
+ /** The session JSON sent at the start: exactly the fields of qlab-api's closed schema. consentTextSha256: the
18
+ * hash of an app's own wording the learner agreed to (2.0.1), sent next to consent_version only then. */
18
19
  export function sessionJson({ modelRevision = null, backend = 'exact', weightsSha256 = null, sdkVersion = SDK_VERSION,
19
- consentVersion = null, contributor, day, deviceClass, osMajor, inputSampleRate, inputRoute = 'unknown',
20
+ consentVersion = null, consentTextSha256 = null, contributor, day, deviceClass, osMajor, inputSampleRate, inputRoute = 'unknown',
20
21
  contributorKey = null, recoveryHash = null }) {
21
22
  if (contributorKey !== null && !/^[A-Za-z0-9_-]{87}$/.test(contributorKey)) throw new TypeError('contributor_key: base64url of the 65-byte point');
22
23
  if (recoveryHash !== null && !HEX64.test(recoveryHash)) throw new TypeError('recovery_hash: 64 lowercase hex');
@@ -24,12 +25,16 @@ export function sessionJson({ modelRevision = null, backend = 'exact', weightsSh
24
25
  if (!DEVICE_RE.test(deviceClass)) throw new TypeError(`device_class ${deviceClass}`);
25
26
  if (!(Number.isInteger(osMajor) && osMajor >= 1 && osMajor <= 99)) throw new TypeError(`os_major ${osMajor}`);
26
27
  if (consentVersion !== null && !CONSENT_RE.test(consentVersion)) throw new TypeError('consent version: 1 to 32 of A-Z a-z 0-9 . _ -');
28
+ if (consentTextSha256 !== null && !(HEX64.test(consentTextSha256) && consentVersion === `custom-${consentTextSha256.slice(0, 24)}`)) {
29
+ throw new TypeError('consent_text_sha256: 64 lowercase hex, with the custom-<24 hex> consent version it derives');
30
+ }
27
31
  if (!INPUT_ROUTES.includes(inputRoute)) throw new TypeError(`input_route ${inputRoute}`);
28
32
  if (!['neuralEngine', 'exact', 'mock'].includes(backend)) throw new TypeError(`backend ${backend}`);
29
33
  const audio = { codec: 'opus', container: 'ogg', sample_rate: 48000, channels: 1, input_route: inputRoute };
30
34
  if (inputSampleRate >= 8000 && inputSampleRate <= 192000) audio.input_sample_rate = Math.round(inputSampleRate);
31
35
  const o = {
32
36
  audio,
37
+ consent_text_sha256: consentTextSha256,
33
38
  consent_version: consentVersion,
34
39
  contributor,
35
40
  contributor_key: contributorKey,
@@ -42,6 +47,8 @@ export function sessionJson({ modelRevision = null, backend = 'exact', weightsSh
42
47
  recovery_hash: recoveryHash,
43
48
  };
44
49
  if (consentVersion === null) delete o.consent_version;
50
+ // absent for the deck's own wording: a 2.0.0 server's closed schema refuses fields it does not know
51
+ if (consentTextSha256 === null) delete o.consent_text_sha256;
45
52
  if (contributorKey === null) delete o.contributor_key;
46
53
  if (recoveryHash === null) delete o.recovery_hash;
47
54
  // sorted keys, as the Swift SDK writes it
@@ -1,4 +1,4 @@
1
- // Type definitions for the TajweedFormer V4 API (@quran-lab/tajweedformer 2.0.0).
1
+ // Type definitions for the TajweedFormer V4 API (@quran-lab/tajweedformer 2.0.1).
2
2
 
3
3
  // ---------------------------------------------------------------------------------------------
4
4
  // Names
@@ -183,7 +183,7 @@ export declare class TajweedSettings {
183
183
  // Model folders and the signed manifest
184
184
  // ---------------------------------------------------------------------------------------------
185
185
 
186
- export declare const SDK_VERSION: '2.0.0';
186
+ export declare const SDK_VERSION: '2.0.1';
187
187
  export declare const SUPPORTED_MANIFEST_FORMATS: readonly number[];
188
188
  export declare const SUPPORTED_ENGINE_FORMATS: readonly number[];
189
189
  export declare const ENGINE_FORMAT_TAJWEEDFORMER: 2;
@@ -14,7 +14,7 @@
14
14
  import { validateCalibration, TajweedSettingsError } from './settings.js';
15
15
 
16
16
  /** The version of this SDK, compared with a manifest's min_sdk_version. */
17
- export const SDK_VERSION = '2.0.0';
17
+ export const SDK_VERSION = '2.0.1';
18
18
 
19
19
  /** Manifest formats this SDK reads. */
20
20
  export const SUPPORTED_MANIFEST_FORMATS = Object.freeze([1, 2, 3]);