@innspel/core 0.9.0 → 0.9.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.
- package/dist/{chunk-YXWPKEC7.js → chunk-TFDM3JI7.js} +3 -3
- package/dist/{chunk-YXWPKEC7.js.map → chunk-TFDM3JI7.js.map} +1 -1
- package/dist/index.cjs +4 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/telemetri.cjs +1 -1
- package/dist/telemetri.cjs.map +1 -1
- package/dist/telemetri.d.cts +1 -1
- package/dist/telemetri.d.ts +1 -1
- package/dist/telemetri.js +1 -1
- package/dist/{typer-CC_TqepX.d.cts → typer-B4_pFm8Z.d.cts} +1 -1
- package/dist/{typer-CC_TqepX.d.ts → typer-B4_pFm8Z.d.ts} +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Connectivity, R as ResolvedSettings, a as ContextInput, b as CaptureInput, c as CaptureResult, K as KnownIssueQuery, d as KnownIssuesKnownIssueCard, S as SubmissionsSubmissionStatusView, M as MySubmission, P as ProgramsMyPrograms, e as ProgramsParticipationView, f as ProgramsTaskCompletionCreate, g as ProgramsTaskCompletionView, h as ProgramsFollowUpResponseCreate, A as AttachmentInput, i as SubmissionsAttachmentView, Q as QueuedSubmission, F as FlushResult, j as PatternFinding, T as TelemetryEvent, O as OpenFeedbackOptions, k as Presenter,
|
|
2
|
-
export {
|
|
1
|
+
import { C as Connectivity, R as ResolvedSettings, a as ContextInput, b as CaptureInput, c as CaptureResult, K as KnownIssueQuery, d as KnownIssuesKnownIssueCard, S as SubmissionsSubmissionStatusView, I as InnspelStorage, M as MySubmission, P as ProgramsMyPrograms, e as ProgramsParticipationView, f as ProgramsTaskCompletionCreate, g as ProgramsTaskCompletionView, h as ProgramsFollowUpResponseCreate, A as AttachmentInput, i as SubmissionsAttachmentView, Q as QueuedSubmission, F as FlushResult, j as PatternFinding, T as TelemetryEvent, O as OpenFeedbackOptions, k as Presenter, l as InnspelOptions, m as CommonErrorCode, n as SubmissionsAttachmentMime } from './typer-B4_pFm8Z.cjs';
|
|
2
|
+
export { o as AttachmentBody, p as AttachmentOutcome, q as CaptureFeil, r as CaptureOnske, s as Correlation, t as FollowUpKind, u as FollowUpView, v as IdentityProvider, w as InvitationView, x as KnownIssueRef, y as KnownIssueStatus, z as PatternKind, B as Platform, D as ProgramTask, E as ProgramView, G as ReasonCode, H as ReplyView, J as StatusType, L as SubmissionStatus, N as SubmissionType, U as TaskOutcome, V as Telemetry, W as TextMaxLength } from './typer-B4_pFm8Z.cjs';
|
|
3
3
|
|
|
4
4
|
/** Klienten `init` gir deg. Én per app; den er trygg å holde på. */
|
|
5
5
|
interface InnspelClient {
|
|
@@ -30,6 +30,8 @@ interface InnspelClient {
|
|
|
30
30
|
/** «Ja, jeg også» (DD-29): Reach +1 uten ny sak. */
|
|
31
31
|
confirm(knownIssueId: string): Promise<SubmissionsSubmissionStatusView>;
|
|
32
32
|
};
|
|
33
|
+
/** Lagringen verten injiserte. Eksponert så widgetene kan lagre det som er per enhet og aldri skal til plattformen (F14). */
|
|
34
|
+
readonly storage: InnspelStorage;
|
|
33
35
|
readonly subjects: {
|
|
34
36
|
/** «Mine innspill» (DD-27), med køen gjort synlig (DD-41). */
|
|
35
37
|
submissions(): Promise<MySubmission[]>;
|
|
@@ -271,6 +273,6 @@ declare function dekkerAlt(rekter: readonly MaskRect[], bilde: {
|
|
|
271
273
|
* ikke kan lese JSON, og `test/versjon.test.ts` holder den i takt med
|
|
272
274
|
* `package.json`.
|
|
273
275
|
*/
|
|
274
|
-
declare const VERSJON = "0.9.
|
|
276
|
+
declare const VERSJON = "0.9.2";
|
|
275
277
|
|
|
276
|
-
export { AttachmentInput, SubmissionsAttachmentMime as AttachmentMime, SubmissionsAttachmentView as AttachmentView, CaptureInput, CaptureResult, Connectivity, ContextInput, CommonErrorCode as ErrorCode, FlushResult, ProgramsFollowUpResponseCreate as FollowUpResponseCreate, InnspelApiError, type InnspelClient, InnspelConfigError, InnspelOptions, InnspelQueueFullError, KONTEKST_FELTER, KO_TAK, KnownIssuesKnownIssueCard as KnownIssueCard, KnownIssueQuery, type MaskPoint, type MaskRect, ProgramsMyPrograms as MyPrograms, MySubmission, OpenFeedbackOptions, ProgramsParticipationView as ParticipationView, PatternFinding, Presenter, QueuedSubmission, ResolvedSettings, SubmissionsSubmissionStatusView as SubmissionStatusView, TILLATTE_MIME, ProgramsTaskCompletionCreate as TaskCompletionCreate, ProgramsTaskCompletionView as TaskCompletionView, TelemetryEvent, VEDLEGG_GRENSER, VERSJON, dekkerAlt, init, klipp, scanText, skaler, strokTilRekter, treffer, trykkTilRekt };
|
|
278
|
+
export { AttachmentInput, SubmissionsAttachmentMime as AttachmentMime, SubmissionsAttachmentView as AttachmentView, CaptureInput, CaptureResult, Connectivity, ContextInput, CommonErrorCode as ErrorCode, FlushResult, ProgramsFollowUpResponseCreate as FollowUpResponseCreate, InnspelApiError, type InnspelClient, InnspelConfigError, InnspelOptions, InnspelQueueFullError, InnspelStorage, KONTEKST_FELTER, KO_TAK, KnownIssuesKnownIssueCard as KnownIssueCard, KnownIssueQuery, type MaskPoint, type MaskRect, ProgramsMyPrograms as MyPrograms, MySubmission, OpenFeedbackOptions, ProgramsParticipationView as ParticipationView, PatternFinding, Presenter, QueuedSubmission, ResolvedSettings, SubmissionsSubmissionStatusView as SubmissionStatusView, TILLATTE_MIME, ProgramsTaskCompletionCreate as TaskCompletionCreate, ProgramsTaskCompletionView as TaskCompletionView, TelemetryEvent, VEDLEGG_GRENSER, VERSJON, dekkerAlt, init, klipp, scanText, skaler, strokTilRekter, treffer, trykkTilRekt };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Connectivity, R as ResolvedSettings, a as ContextInput, b as CaptureInput, c as CaptureResult, K as KnownIssueQuery, d as KnownIssuesKnownIssueCard, S as SubmissionsSubmissionStatusView, M as MySubmission, P as ProgramsMyPrograms, e as ProgramsParticipationView, f as ProgramsTaskCompletionCreate, g as ProgramsTaskCompletionView, h as ProgramsFollowUpResponseCreate, A as AttachmentInput, i as SubmissionsAttachmentView, Q as QueuedSubmission, F as FlushResult, j as PatternFinding, T as TelemetryEvent, O as OpenFeedbackOptions, k as Presenter,
|
|
2
|
-
export {
|
|
1
|
+
import { C as Connectivity, R as ResolvedSettings, a as ContextInput, b as CaptureInput, c as CaptureResult, K as KnownIssueQuery, d as KnownIssuesKnownIssueCard, S as SubmissionsSubmissionStatusView, I as InnspelStorage, M as MySubmission, P as ProgramsMyPrograms, e as ProgramsParticipationView, f as ProgramsTaskCompletionCreate, g as ProgramsTaskCompletionView, h as ProgramsFollowUpResponseCreate, A as AttachmentInput, i as SubmissionsAttachmentView, Q as QueuedSubmission, F as FlushResult, j as PatternFinding, T as TelemetryEvent, O as OpenFeedbackOptions, k as Presenter, l as InnspelOptions, m as CommonErrorCode, n as SubmissionsAttachmentMime } from './typer-B4_pFm8Z.js';
|
|
2
|
+
export { o as AttachmentBody, p as AttachmentOutcome, q as CaptureFeil, r as CaptureOnske, s as Correlation, t as FollowUpKind, u as FollowUpView, v as IdentityProvider, w as InvitationView, x as KnownIssueRef, y as KnownIssueStatus, z as PatternKind, B as Platform, D as ProgramTask, E as ProgramView, G as ReasonCode, H as ReplyView, J as StatusType, L as SubmissionStatus, N as SubmissionType, U as TaskOutcome, V as Telemetry, W as TextMaxLength } from './typer-B4_pFm8Z.js';
|
|
3
3
|
|
|
4
4
|
/** Klienten `init` gir deg. Én per app; den er trygg å holde på. */
|
|
5
5
|
interface InnspelClient {
|
|
@@ -30,6 +30,8 @@ interface InnspelClient {
|
|
|
30
30
|
/** «Ja, jeg også» (DD-29): Reach +1 uten ny sak. */
|
|
31
31
|
confirm(knownIssueId: string): Promise<SubmissionsSubmissionStatusView>;
|
|
32
32
|
};
|
|
33
|
+
/** Lagringen verten injiserte. Eksponert så widgetene kan lagre det som er per enhet og aldri skal til plattformen (F14). */
|
|
34
|
+
readonly storage: InnspelStorage;
|
|
33
35
|
readonly subjects: {
|
|
34
36
|
/** «Mine innspill» (DD-27), med køen gjort synlig (DD-41). */
|
|
35
37
|
submissions(): Promise<MySubmission[]>;
|
|
@@ -271,6 +273,6 @@ declare function dekkerAlt(rekter: readonly MaskRect[], bilde: {
|
|
|
271
273
|
* ikke kan lese JSON, og `test/versjon.test.ts` holder den i takt med
|
|
272
274
|
* `package.json`.
|
|
273
275
|
*/
|
|
274
|
-
declare const VERSJON = "0.9.
|
|
276
|
+
declare const VERSJON = "0.9.2";
|
|
275
277
|
|
|
276
|
-
export { AttachmentInput, SubmissionsAttachmentMime as AttachmentMime, SubmissionsAttachmentView as AttachmentView, CaptureInput, CaptureResult, Connectivity, ContextInput, CommonErrorCode as ErrorCode, FlushResult, ProgramsFollowUpResponseCreate as FollowUpResponseCreate, InnspelApiError, type InnspelClient, InnspelConfigError, InnspelOptions, InnspelQueueFullError, KONTEKST_FELTER, KO_TAK, KnownIssuesKnownIssueCard as KnownIssueCard, KnownIssueQuery, type MaskPoint, type MaskRect, ProgramsMyPrograms as MyPrograms, MySubmission, OpenFeedbackOptions, ProgramsParticipationView as ParticipationView, PatternFinding, Presenter, QueuedSubmission, ResolvedSettings, SubmissionsSubmissionStatusView as SubmissionStatusView, TILLATTE_MIME, ProgramsTaskCompletionCreate as TaskCompletionCreate, ProgramsTaskCompletionView as TaskCompletionView, TelemetryEvent, VEDLEGG_GRENSER, VERSJON, dekkerAlt, init, klipp, scanText, skaler, strokTilRekter, treffer, trykkTilRekt };
|
|
278
|
+
export { AttachmentInput, SubmissionsAttachmentMime as AttachmentMime, SubmissionsAttachmentView as AttachmentView, CaptureInput, CaptureResult, Connectivity, ContextInput, CommonErrorCode as ErrorCode, FlushResult, ProgramsFollowUpResponseCreate as FollowUpResponseCreate, InnspelApiError, type InnspelClient, InnspelConfigError, InnspelOptions, InnspelQueueFullError, InnspelStorage, KONTEKST_FELTER, KO_TAK, KnownIssuesKnownIssueCard as KnownIssueCard, KnownIssueQuery, type MaskPoint, type MaskRect, ProgramsMyPrograms as MyPrograms, MySubmission, OpenFeedbackOptions, ProgramsParticipationView as ParticipationView, PatternFinding, Presenter, QueuedSubmission, ResolvedSettings, SubmissionsSubmissionStatusView as SubmissionStatusView, TILLATTE_MIME, ProgramsTaskCompletionCreate as TaskCompletionCreate, ProgramsTaskCompletionView as TaskCompletionView, TelemetryEvent, VEDLEGG_GRENSER, VERSJON, dekkerAlt, init, klipp, scanText, skaler, strokTilRekter, treffer, trykkTilRekt };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createClient, createConfig, VERSJON, submissionsListMine, knownIssuesList2, configGet, submissionsCreate, attachmentsPresign, attachmentsComplete, programsRespond, programsCompleteTask, programsWithdraw, programsDecline, programsAccept, programsListMine, submissionsStatus, knownIssuesConfirm } from './chunk-
|
|
2
|
-
export { VERSJON } from './chunk-
|
|
1
|
+
import { createClient, createConfig, VERSJON, submissionsListMine, knownIssuesList2, configGet, submissionsCreate, attachmentsPresign, attachmentsComplete, programsRespond, programsCompleteTask, programsWithdraw, programsDecline, programsAccept, programsListMine, submissionsStatus, knownIssuesConfirm } from './chunk-TFDM3JI7.js';
|
|
2
|
+
export { VERSJON } from './chunk-TFDM3JI7.js';
|
|
3
3
|
|
|
4
4
|
// src/feil.ts
|
|
5
5
|
var PREFIKS = "[innspel]";
|
|
@@ -569,6 +569,7 @@ function init(options) {
|
|
|
569
569
|
connectivity: options.connectivity ?? null,
|
|
570
570
|
settings,
|
|
571
571
|
context: kontekst,
|
|
572
|
+
storage: options.storage,
|
|
572
573
|
async loadSettings() {
|
|
573
574
|
try {
|
|
574
575
|
const cfg = await medToken(
|
|
@@ -641,6 +642,7 @@ function init(options) {
|
|
|
641
642
|
},
|
|
642
643
|
knownIssues: {
|
|
643
644
|
async for(query = {}) {
|
|
645
|
+
const version = query.version ?? kontekst.appVersion;
|
|
644
646
|
try {
|
|
645
647
|
const kort = await medToken(
|
|
646
648
|
(h, s) => knownIssuesList2({
|
|
@@ -649,7 +651,7 @@ function init(options) {
|
|
|
649
651
|
signal: s,
|
|
650
652
|
query: {
|
|
651
653
|
...query.screen !== void 0 ? { screen: query.screen } : {},
|
|
652
|
-
...
|
|
654
|
+
...version !== void 0 ? { version } : {},
|
|
653
655
|
platform: query.platform ?? kontekst.platform
|
|
654
656
|
}
|
|
655
657
|
})
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/feil.ts","../src/identitet.ts","../src/flush.ts","../src/ko.ts","../src/kontekst.ts","../src/monster.ts","../src/uuid.ts","../src/vedlegg.ts","../src/klient.ts","../src/maskering.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ErrorCode } from './api.js';\n\n/** Prefikset alle utviklerrettede meldinger fra SDK-et bærer. */\nexport const PREFIKS = '[innspel]';\n\n/**\n * En HTTP-headerverdi må være en ByteString: synlige ASCII-tegn, ingen\n * mellomrom, linjeskift eller tegn over U+00FF. Brytes det, kaster\n * `new Request(...)` en `TypeError` — og den er umulig å skille fra «nettet er\n * nede», så en utviklerfeil ville sett ut som en innsending som venter på nett.\n *\n * Funnet ved å kjøre quickstarten i et tomt prosjekt: README-placeholderen\n * `ik_pub_…` inneholder U+2026.\n */\nexport function erHeaderTrygg(verdi: string): boolean {\n return /^[\\x21-\\x7e]+$/.test(verdi);\n}\n\n/**\n * Utviklerfeil: opsjoner som er feil eller mangler, kontekstfelter utenfor\n * hvitelisten, tekst utenfor grensene. Kastes umiddelbart og navngir feltet —\n * aldri en stille tom widget (tech-decisions.md, «SDK — dokumentasjon og\n * utvikleropplevelse»).\n */\nexport class InnspelConfigError extends Error {\n override readonly name = 'InnspelConfigError';\n /** Feltet som er galt, slik det heter i `init`-opsjonene. */\n readonly field: string;\n\n constructor(field: string, hva: string, hvor = 'README.md') {\n super(`${PREFIKS} ${field}: ${hva}. Se ${hvor}.`);\n this.field = field;\n }\n}\n\n/**\n * Feil fra plattformen. Forgren på `code`, aldri på `message` — meldingen er\n * for mennesker og kan endres uten varsel (contracts/models/common.tsp).\n */\nexport class InnspelApiError extends Error {\n override readonly name = 'InnspelApiError';\n readonly code: ErrorCode | 'unknown';\n readonly status: number;\n /** Sekunder til neste forsøk, fra Retry-After. Kun ved 429. */\n readonly retryAfter: number | undefined;\n\n constructor(status: number, code: ErrorCode | 'unknown', message: string, retryAfter?: number) {\n super(message);\n this.status = status;\n this.code = code;\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Intern, eksporteres ikke: `fetch` selv kastet — ingen forbindelse, eller\n * tidsgrensen avbrøt kallet. Bare denne legger en innsending i offline-køen. Alt\n * annet uten svar er en feil i koden og skal synes, ikke se ut som «Ingen nett».\n */\nexport class NettverksFeil extends Error {}\n\n/**\n * Offline-køen er full. Taket er 30 (DD-41), og den eldste beholdes: det første\n * innspillet er like mye verdt som det siste, og å kaste det stille ville brutt\n * løftet om at teksten aldri mistes.\n */\nexport class InnspelQueueFullError extends Error {\n override readonly name = 'InnspelQueueFullError';\n readonly code = 'queue_full' as const;\n /** Tekst som kan vises til innsenderen. Køen skal være synlig, ikke stille. */\n readonly userMessage: string;\n\n constructor(tak: number) {\n super(`${PREFIKS} offline-køen er full (${tak}).`);\n this.userMessage = `Du har ${tak} innspill som venter på nett. Send dem før du skriver flere — de sendes automatisk når du er på nett igjen.`;\n }\n}\n","import { erHeaderTrygg, PREFIKS } from './feil.js';\nimport type { IdentityProvider } from './typer.js';\n\n/**\n * Henter et ferskt feedback-token fra verten.\n *\n * Tokenet lagres ALDRI (K20, DD-41): det er gyldig i høyst 15 minutter, og ved\n * en flush av offline-køen er det gamle utløpt for lengst. Kjernen ber om et\n * nytt hver gang den trenger ett.\n *\n * Kaster vertens funksjon, eller returnerer den `null`, går kallet anonymt.\n * Innsenderen skal kunne melde fra selv om vertens innlogging er nede — men det\n * er en utviklerfeil, så den går til `console.error` med `[innspel]`-prefiks\n * (tech-decisions.md, «SDK — dokumentasjon og utvikleropplevelse»).\n */\nexport async function hentToken(\n provider: IdentityProvider | null,\n): Promise<string | null> {\n if (provider === null) return null;\n\n try {\n const token = await provider();\n if (typeof token !== 'string' || token.length === 0) return null;\n\n // Et token som ikke kan bli en headerverdi ville fått Request-byggingen til\n // å kaste en TypeError, og den er ikke til å skille fra «nettet er nede» —\n // innsendingen ville havnet i offline-køen og sett ut som om den venter på\n // nett. Feil i token-endepunktet skal være synlig som nettopp det.\n if (!erHeaderTrygg(token)) {\n console.error(\n `${PREFIKS} identityProvider ga et token med tegn som ikke kan stå i en HTTP-header (mellomrom, linjeskift eller tegn utenfor ASCII). Et JWT er base64url og har ingen slike. Innsendingen går anonymt — se docs/sdk/README.md.`,\n );\n return null;\n }\n\n return token;\n } catch (e) {\n console.error(\n `${PREFIKS} identityProvider kastet. Innsendingen går anonymt og kan ikke følges opp. Rett feilen i token-endepunktet — se docs/sdk/README.md.`,\n e,\n );\n return null;\n }\n}\n","import { InnspelApiError } from './feil.js';\nimport type { Ko } from './ko.js';\nimport type { FlushResult, QueuedSubmission, Telemetry } from './typer.js';\n\n/**\n * Tømmer offline-køen. Kalles når widgeten åpnes eller når appen får nett med\n * widgeten åpen — **aldri ved oppstart** (DD-41).\n *\n * Hver rad sendes med et FERSKT token: det gamle er utløpt for lengst (exp ≤ 15\n * min). Det er `send` som henter det, én gang per rad.\n *\n * To utfall skiller seg:\n * - **4xx** — plattformen avviste kroppen. Den blir aldri gyldig, så raden\n * forkastes i stedet for å prøves i evighet. Innsenderen skal ikke ha en rad\n * som står og «venter på nett» for alltid.\n * - **nettverksfeil** — nettet er nede igjen. Resten står, og vi stopper: de\n * neste radene ville feilet på samme måte, og hvert forsøk koster rate limit.\n */\nexport async function flushKo(\n kø: Ko,\n send: (rad: QueuedSubmission) => Promise<unknown>,\n telemetri: Telemetry,\n): Promise<FlushResult> {\n const rader = await kø.les();\n let sent = 0;\n let failed = 0;\n\n for (const rad of rader) {\n try {\n await send(rad);\n await kø.fjern(rad.clientRef);\n sent++;\n } catch (e) {\n if (e instanceof InnspelApiError && e.status >= 400 && e.status < 500) {\n await kø.fjern(rad.clientRef);\n failed++;\n telemetri.emit({ name: 'submission_failed', reason: e.code });\n continue;\n }\n break;\n }\n }\n\n return { sent, failed, remaining: await kø.antall() };\n}\n","import { InnspelQueueFullError } from './feil.js';\nimport type { InnspelStorage, QueuedSubmission } from './typer.js';\n\n/**\n * DD-41 — «Offline-køen er maks 30, tømmes aldri ved oppstart, og er synlig.»\n *\n * Kilde: Sentry `maxQueueSize` 30 og `flushAtStartup` false; Shake «Feedback\n * pending sync» er den eneste leverandøren som viser tilstanden til brukeren.\n * Kvitteringen i DD-07 kan ikke love svar på noe som ikke er sendt — derfor er\n * køen synlig i «Mine innspill», ikke en usynlig bakgrunnsjobb.\n *\n * Rate limit-tallet per subject i M1.1 er satt til 60 nettopp for at en full kø\n * på 30 skal kunne tømmes på ett minutt (tech-decisions.md, «M1.1»).\n */\nexport const KO_TAK = 30;\n\nconst NØKKEL = 'innspel:queue';\n\nexport class Ko {\n readonly #storage: InnspelStorage;\n\n constructor(storage: InnspelStorage) {\n this.#storage = storage;\n }\n\n /**\n * Leser køen. En ødelagt rad i lagringen gir tom kø, ikke et unntak: en\n * halvskrevet JSON etter at appen ble drept skal ikke hindre innsenderen i å\n * melde fra på nytt.\n */\n async les(): Promise<QueuedSubmission[]> {\n const rå = await this.#storage.get(NØKKEL);\n if (!rå) return [];\n try {\n const parset: unknown = JSON.parse(rå);\n return Array.isArray(parset) ? (parset as QueuedSubmission[]) : [];\n } catch {\n return [];\n }\n }\n\n async #skriv(rader: QueuedSubmission[]): Promise<void> {\n if (rader.length === 0) {\n await this.#storage.remove(NØKKEL);\n return;\n }\n await this.#storage.set(NØKKEL, JSON.stringify(rader));\n }\n\n /**\n * Legger en innsending bakerst.\n *\n * Ved fullt tak kastes {@link InnspelQueueFullError} — den eldste beholdes.\n * Å kaste den eldste ville vært stille tap av noe innsenderen tror er sendt.\n */\n async leggTil(rad: QueuedSubmission): Promise<void> {\n const rader = await this.les();\n if (rader.length >= KO_TAK) throw new InnspelQueueFullError(KO_TAK);\n rader.push(rad);\n await this.#skriv(rader);\n }\n\n async fjern(clientRef: string): Promise<void> {\n const rader = await this.les();\n await this.#skriv(rader.filter((r) => r.clientRef !== clientRef));\n }\n\n async antall(): Promise<number> {\n return (await this.les()).length;\n }\n}\n","import { InnspelConfigError } from './feil.js';\nimport type { ContextInput, Platform } from './typer.js';\n\n/**\n * Den lukkede hvitelista (K5), som feltnavn. Listen er kilden både til\n * valideringen og til det som faktisk sendes — et felt som ikke står her kommer\n * aldri ut av kjernen, uansett hva verten fyller inn.\n *\n * `sdkVersion` står ikke her fordi den ikke kommer fra verten: kjernen setter\n * den selv, og en vert som prøver å overstyre den blir ignorert.\n */\nexport const KONTEKST_FELTER = [\n 'platform',\n 'appVersion',\n 'build',\n 'os',\n 'screen',\n 'locale',\n] as const;\n\nconst PLATTFORMER: readonly Platform[] = [\n 'ios',\n 'android',\n 'web',\n 'tvos',\n 'androidtv',\n 'tizen',\n 'webos',\n];\n\n/**\n * Sjekker et kontekstobjekt mot hvitelisten og kaster med feltnavnet ved avvik.\n *\n * Plattformen ville svart 400 `unknown_field` på det samme, men da har\n * innsenderen allerede skrevet ferdig. Kjernen feiler i stedet ved `init`, mens\n * utvikleren står i det (tech-decisions.md, «Feil bruk feiler høyt og tidlig»).\n *\n * @param kontekst Rå kontekst fra verten.\n * @param sti Feltnavnet i feilmeldingen — `context` fra `init`, ellers `capture`.\n * @param krevPlatform `platform` er påkrevd i `init`, valgfri i et enkeltkall\n * som bare legger på `screen`.\n */\nexport function validerKontekst(\n kontekst: Partial<ContextInput>,\n sti: string,\n krevPlatform: boolean,\n): void {\n if (kontekst === null || typeof kontekst !== 'object') {\n throw new InnspelConfigError(sti, 'må være et objekt med minst { platform }');\n }\n\n for (const nøkkel of Object.keys(kontekst)) {\n if (!(KONTEKST_FELTER as readonly string[]).includes(nøkkel)) {\n throw new InnspelConfigError(\n `${sti}.${nøkkel}`,\n `er ikke i kontekst-hvitelisten. Tillatt: ${KONTEKST_FELTER.join(', ')}. Lista er lukket (K5) — enhets-ID, IP og skjerminnhold hører ikke hjemme her`,\n );\n }\n }\n\n const plattform = kontekst.platform;\n if (krevPlatform && plattform === undefined) {\n throw new InnspelConfigError(`${sti}.platform`, 'er påkrevd');\n }\n if (plattform !== undefined && !PLATTFORMER.includes(plattform)) {\n throw new InnspelConfigError(\n `${sti}.platform`,\n `må være en av ${PLATTFORMER.join(', ')}`,\n );\n }\n}\n\n/**\n * Slår sammen konteksten fra `init` med det enkeltkallet legger på, og setter\n * `sdkVersion` til slutt så den ikke kan overstyres.\n *\n * Et felt som STÅR i kallets kontekst med verdien `undefined` eller `null`\n * FJERNES — det er «Fjern» i kontekstlinja (DD-05). Et felt som ikke står der,\n * beholdes fra `init`. Skillet er `in`, ikke `??`: før 0.2.1 fylte kjernen et\n * fjernet felt fra `init` igjen, og «Fjern» i widgeten var en løgn.\n */\nexport function slåSammenKontekst(\n base: ContextInput,\n påLagt: Partial<ContextInput> | undefined,\n sdkVersion: string,\n): ContextInput & { sdkVersion: string } {\n const ut: Record<string, unknown> = {};\n for (const felt of KONTEKST_FELTER) {\n const verdi = påLagt && felt in påLagt ? påLagt[felt] : base[felt];\n if (verdi !== undefined && verdi !== null) ut[felt] = verdi;\n }\n ut['sdkVersion'] = sdkVersion;\n return ut as unknown as ContextInput & { sdkVersion: string };\n}\n","import type { PatternFinding, PatternKind } from './typer.js';\n\n/**\n * DD-46 — mønstervarsel før sending, aldri stille redaksjon.\n *\n * Shake redigerer de samme mønstrene, men stille og kun i logger. Innspel har\n * ingen logger: teksten ER innspillet, og en stille endring ville gjort\n * innsenderen til usikker kilde på sin egen sak. Derfor returnerer denne\n * funksjonen FUNN. Den fjerner aldri noe — «Fjern» eller «Behold» er\n * innsenderens valg (DD-05).\n *\n * Regex i kjernen, ingen avhengighet (K19).\n */\n\ninterface Regel {\n kind: PatternKind;\n re: RegExp;\n /** Ekstra sjekk der formen alene gir for mange falske varsler. */\n gyldig?: (treff: string) => boolean;\n}\n\n/**\n * Luhn. Uten den varsles hvert 16-sifrede ordrenummer som kortnummer, og et\n * varsel som stemmer sjelden lærer folk å trykke «Behold» uten å lese.\n */\nfunction luhn(siffer: string): boolean {\n let sum = 0;\n let annenhver = false;\n for (let i = siffer.length - 1; i >= 0; i--) {\n let n = siffer.charCodeAt(i) - 48;\n if (n < 0 || n > 9) return false;\n if (annenhver) {\n n *= 2;\n if (n > 9) n -= 9;\n }\n sum += n;\n annenhver = !annenhver;\n }\n return sum % 10 === 0;\n}\n\nfunction gyldigIp(treff: string): boolean {\n const deler = treff.split('.');\n return deler.length === 4 && deler.every((d) => d.length <= 3 && Number(d) <= 255);\n}\n\nconst REGLER: Regel[] = [\n {\n kind: 'email',\n re: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}/g,\n },\n {\n // JWT-form først: tre base64url-segmenter. Fanger et feedback-token limt\n // inn fra en feilmelding — nøyaktig det innsenderen ikke bør sende.\n //\n // Siste segment krever bare 4 tegn. En ekte ES256-signatur er ~86, men et\n // token som er avkortet i en feilmelding er like uønsket i innspillsteksten,\n // og de to første segmentene på 16+ base64url-tegn hver gjør falske treff i\n // norsk prosa nesten umulige.\n kind: 'token',\n re: /\\b[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{4,}\\b|\\b(?:sk|pk|ghp|xox[abpr])[-_][A-Za-z0-9_-]{16,}\\b/g,\n },\n {\n kind: 'card',\n // 13–19 siffer med valgfrie mellomrom eller bindestrek mellom grupper.\n re: /\\b(?:\\d[ -]?){12,18}\\d\\b/g,\n gyldig: (t) => {\n const siffer = t.replace(/[^\\d]/g, '');\n return siffer.length >= 13 && siffer.length <= 19 && luhn(siffer);\n },\n },\n {\n kind: 'ip',\n re: /\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b/g,\n gyldig: gyldigIp,\n },\n {\n kind: 'phone',\n // Norsk form: 8 siffer, med eller uten +47/0047 og gruppering.\n re: /(?:\\+47|0047)?[ ]?(?:\\d[ ]?){8}(?![ ]?\\d)/g,\n gyldig: (t) => {\n const siffer = t.replace(/[^\\d]/g, '');\n const uten = siffer.replace(/^(?:47|0047)/, '');\n return uten.length === 8;\n },\n },\n];\n\n/**\n * Leter etter e-post, telefonnummer, kortnummer (Luhn-validert), IP-adresser og\n * token-lignende strenger i en innspillstekst.\n *\n * Rekkefølgen på reglene er bevisst: de spesifikke først, så et treff som\n * allerede er dekket av en sterkere regel ikke varsles to ganger. Et kortnummer\n * er ikke også et telefonnummer.\n *\n * @param text Teksten innsenderen har skrevet. Endres ikke.\n * @returns Funnene med posisjon, så verten kan markere dem i feltet. Tom liste\n * for en vanlig innsending.\n */\nexport function scanText(text: string): PatternFinding[] {\n const funn: PatternFinding[] = [];\n const opptatt: Array<[number, number]> = [];\n\n for (const regel of REGLER) {\n regel.re.lastIndex = 0;\n let treff: RegExpExecArray | null;\n while ((treff = regel.re.exec(text)) !== null) {\n const rå = treff[0];\n const trimmet = rå.trim();\n if (!trimmet) continue;\n\n const start = treff.index + rå.indexOf(trimmet);\n const end = start + trimmet.length;\n\n if (regel.gyldig && !regel.gyldig(trimmet)) continue;\n if (opptatt.some(([a, b]) => start < b && end > a)) continue;\n\n opptatt.push([start, end]);\n funn.push({ kind: regel.kind, match: trimmet, start, end });\n }\n }\n\n return funn.sort((a, b) => a.start - b.start);\n}\n","/**\n * `clientRef` — en tilfeldig UUID per INNSENDING, aldri per enhet eller\n * installasjon (K20, og kontraktens `SubmissionCreateBase.clientRef`). Den er\n * en idempotensnøkkel for offline-køen, ikke en identitet: to innsendinger fra\n * samme telefon deler den aldri.\n *\n * Bruker `crypto.randomUUID` der den finnes (Node, moderne nettlesere) og\n * faller tilbake til `Math.random` ellers — React Native har ingen WebCrypto\n * uten polyfill, og kjernen skal ikke kreve en (K19). Fallbacken er god nok:\n * nøkkelen er ikke en hemmelighet, og kollisjonsvinduet er én innsender i 24\n * timer.\n */\nexport function nyClientRef(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (typeof c?.randomUUID === 'function') return c.randomUUID();\n\n const hex: string[] = [];\n for (let i = 0; i < 36; i++) {\n if (i === 8 || i === 13 || i === 18 || i === 23) {\n hex.push('-');\n } else if (i === 14) {\n hex.push('4');\n } else if (i === 19) {\n hex.push(((Math.random() * 4) | 8).toString(16));\n } else {\n hex.push(((Math.random() * 16) | 0).toString(16));\n }\n }\n return hex.join('');\n}\n","import type { AttachmentMime } from './api.js';\nimport { InnspelApiError, InnspelConfigError } from './feil.js';\nimport type { AttachmentBody, AttachmentInput } from './typer.js';\n\n/**\n * Grensene for et vedlegg (K9). Tallene er kontraktens\n * (`AttachmentPresignRequest`: 5 MB, 4096²) og sjekkes her FØR noe går på\n * nettet — plattformen sjekker dem på nytt før dekoding.\n */\nexport const VEDLEGG_GRENSER = {\n maxBytes: 5_242_880,\n maxDimension: 4096,\n} as const;\n\n/** Allowlisten (K9): aldri SVG, aldri GIF. Avgjøres på ledningen av magic bytes, ikke av denne strengen. */\nexport const TILLATTE_MIME: readonly AttachmentMime[] = ['image/png', 'image/jpeg', 'image/webp'];\n\n/** Byte-lengden på kroppen, uansett om verten gir Blob, ArrayBuffer eller en typed array. */\nexport function byteLengde(body: AttachmentBody): number {\n if (typeof body === 'object' && body !== null && 'size' in body && typeof body.size === 'number') {\n return body.size;\n }\n return (body as ArrayBuffer | ArrayBufferView).byteLength;\n}\n\n/**\n * Validerer vedlegget slik `init` validerer opsjonene: kaster {@link InnspelConfigError}\n * med feltnavn, før noe treffer nettet. Et vedlegg over grensene er en utviklerfeil\n * i vertens fangst — ikke noe innsenderen skal få 413 for etter å ha ventet.\n */\nexport function validerVedlegg(input: AttachmentInput): void {\n if (input === null || typeof input !== 'object') {\n throw new InnspelConfigError('attachment', 'må være et objekt med { submissionId?, mime, body, width, height }');\n }\n if (!TILLATTE_MIME.includes(input.mime)) {\n throw new InnspelConfigError(\n 'attachment.mime',\n `må være en av ${TILLATTE_MIME.join(', ')}. SVG og GIF er aldri tillatt (K9)`,\n );\n }\n if (input.body === null || input.body === undefined) {\n throw new InnspelConfigError('attachment.body', 'mangler — send bildet som Blob, ArrayBuffer eller Uint8Array');\n }\n const bytes = byteLengde(input.body);\n if (!Number.isFinite(bytes) || bytes < 1) {\n throw new InnspelConfigError('attachment.body', 'er tom');\n }\n if (bytes > VEDLEGG_GRENSER.maxBytes) {\n throw new InnspelConfigError(\n 'attachment.body',\n `er ${bytes} byte, over taket på ${VEDLEGG_GRENSER.maxBytes} (5 MB). Reduser kvaliteten eller oppløsningen ved fangst`,\n );\n }\n for (const felt of ['width', 'height'] as const) {\n const v = input[felt];\n if (!Number.isInteger(v) || v < 1 || v > VEDLEGG_GRENSER.maxDimension) {\n throw new InnspelConfigError(\n `attachment.${felt}`,\n `må være et heltall mellom 1 og ${VEDLEGG_GRENSER.maxDimension} (K9)`,\n );\n }\n }\n}\n\n/** Det presign svarer med, slik `lastOpp` trenger det. */\nexport interface PresignSvar {\n attachmentId: string;\n uploadUrl: string;\n headers: ReadonlyArray<{ name: string; value: string }>;\n}\n\n/**\n * PUT mot den presignede URL-en, med NØYAKTIG headerne presign ga — settet er\n * lukket, og lagringen avviser alt annet (signaturen dekker `Content-Type`).\n *\n * En egen funksjon fordi den ikke går gjennom den genererte klienten: URL-en\n * peker på lagringen, ikke på plattformen, og skal hverken ha tenantKey eller\n * token. En nettverksfeil kastes videre som den er, så kalleren kan skille\n * «nettet er nede» fra «lagringen sa nei».\n */\nexport async function lastOppTilLagring(\n fetchImpl: typeof fetch,\n presign: PresignSvar,\n body: AttachmentBody,\n signal: AbortSignal,\n): Promise<void> {\n const headers: Record<string, string> = {};\n for (const h of presign.headers) headers[h.name] = h.value;\n\n const res = await fetchImpl(new Request(presign.uploadUrl, { method: 'PUT', headers, body, signal }));\n if (!res.ok) {\n throw new InnspelApiError(\n res.status,\n 'unknown',\n `Lagringen avviste opplastingen med status ${res.status}. Bildet ble ikke lagt ved.`,\n );\n }\n}\n","import {\n createClient,\n createConfig,\n ingestAttachmentsComplete,\n ingestAttachmentsPresign,\n ingestConfigGet,\n ingestKnownIssuesConfirm,\n ingestKnownIssuesList,\n ingestProgramsAccept,\n ingestProgramsCompleteTask,\n ingestProgramsDecline,\n ingestProgramsListMine,\n ingestProgramsRespond,\n ingestProgramsWithdraw,\n ingestSubmissionsCreate,\n ingestSubmissionsListMine,\n ingestSubmissionsStatus,\n type ApiErrorBody,\n type AttachmentPresign,\n type AttachmentView,\n type Client,\n type ClientConfig,\n type ErrorCode,\n type FollowUpResponseCreate,\n type KnownIssueCard,\n type MyPrograms,\n type ParticipationView,\n type SubmissionStatusView,\n type TaskCompletionCreate,\n type TaskCompletionView,\n} from './api.js';\nimport { erHeaderTrygg, InnspelApiError, InnspelConfigError, NettverksFeil } from './feil.js';\nimport { hentToken } from './identitet.js';\nimport { flushKo } from './flush.js';\nimport { Ko } from './ko.js';\nimport { slåSammenKontekst, validerKontekst } from './kontekst.js';\nimport { scanText } from './monster.js';\nimport type {\n AttachmentInput,\n AttachmentOutcome,\n CaptureInput,\n CaptureResult,\n ContextInput,\n FlushResult,\n InnspelOptions,\n KnownIssueQuery,\n MySubmission,\n OpenFeedbackOptions,\n PatternFinding,\n Presenter,\n QueuedSubmission,\n ResolvedSettings,\n Connectivity,\n Telemetry,\n TelemetryEvent,\n} from './typer.js';\nimport { nyClientRef } from './uuid.js';\nimport { byteLengde, lastOppTilLagring, validerVedlegg } from './vedlegg.js';\nimport { VERSJON } from './versjon.js';\n\nconst STANDARD_TIMEOUT_MS = 10_000;\nconst noopTelemetri: Telemetry = { emit: () => undefined };\nconst UTFALL = ['fungerte', 'delvis', 'ikke'] as const;\nconst SETNING_MAKS = 140;\n\n/** Tre lukkede valg og en setning ≤ 140 — samme form for «Gjort» og «Hvordan gikk det?». Utviklerfeil kastes før noe kall går ut. */\nfunction validerUtfall(input: { outcome: string; text?: string | undefined }): void {\n if (!(UTFALL as readonly string[]).includes(input.outcome)) {\n throw new InnspelConfigError('outcome', `må være ett av ${UTFALL.join(' · ')}`);\n }\n if (input.text !== undefined && (typeof input.text !== 'string' || input.text.length > SETNING_MAKS)) {\n throw new InnspelConfigError('text', `er valgfri, men aldri lengre enn ${SETNING_MAKS} tegn`);\n }\n}\n\n/** Klienten `init` gir deg. Én per app; den er trygg å holde på. */\nexport interface InnspelClient {\n /** Versjonen av `@innspel/core`. Følger med hver innsending som `context.sdkVersion`. */\n readonly version: string;\n /** `true` når `identityProvider` er `null` — innsendinger kan ikke følges opp. */\n readonly isAnonymous: boolean;\n /** Vertens nettstatus fra `init({ connectivity })`, eller `null` — da vet widgeten om nettet først når et kall feiler. */\n readonly connectivity: Connectivity | null;\n /** Leietakerens grenser slik klienten kjenner dem. Oppdateres på plass av {@link loadSettings}. */\n readonly settings: ResolvedSettings;\n /** Konteksten som følger hver innsending, med `sdkVersion` satt av kjernen. */\n readonly context: ContextInput & { sdkVersion: string };\n\n /**\n * Henter leietakerens klientkonfigurasjon (`GET /v1/ingest/config`, M2.5): tegngrense,\n * minste antall tegn, skjermbilde og personvernlenke — det verten ellers måtte\n * duplisere i `init()`. Kalles av widgeten ved åpning, aldri ved oppstart (DD-41).\n * Svarer ikke kallet, beholdes det klienten alt har: konfigurasjonen er et tilbud,\n * aldri en sperre. Returnerer `settings` — samme objekt, oppdatert.\n */\n loadSettings(): Promise<ResolvedSettings>;\n\n capture(input: CaptureInput): Promise<CaptureResult>;\n\n readonly knownIssues: {\n /** Kortene som vises FØR feltet i feilsporet (DD-03). Feiler oppslaget, er lista tom. */\n for(query?: KnownIssueQuery): Promise<KnownIssueCard[]>;\n /** «Ja, jeg også» (DD-29): Reach +1 uten ny sak. */\n confirm(knownIssueId: string): Promise<SubmissionStatusView>;\n };\n\n readonly subjects: {\n /** «Mine innspill» (DD-27), med køen gjort synlig (DD-41). */\n submissions(): Promise<MySubmission[]>;\n status(submissionId: string): Promise<SubmissionStatusView>;\n };\n\n readonly programs: {\n /** Alt om betaprogram for innsenderen i ett kall: invitasjoner til banneret (DD-12), deltakelser til fanen, og oppfølginger som venter. */\n list(): Promise<MyPrograms>;\n /**\n * Aksepterer invitasjonen etter forventningsavklaringen (DD-13, DD-32).\n * Tokenet kom fra leietakerens egen kanal — plattformen sender aldri (DD-12).\n * Er det brukt, utløpt eller utstedt til noen andre, kommer 404\n * `invitation_invalid`. Gjentak fra samme innsender er trygt: svaret er den\n * samme deltakelsen.\n */\n accept(invitationToken: string): Promise<ParticipationView>;\n /** Avslår invitasjonen. Ingen årsak spørres. Et nei etter ja er {@link withdraw}, ikke avslag. */\n decline(invitationToken: string): Promise<void>;\n /** «Gå ut» (DD-36): umiddelbart, alltid tilgjengelig, og aldri en straff. Idempotent. */\n withdraw(participationId: string): Promise<ParticipationView>;\n /**\n * «Gjort» (3c): ett av tre lukkede utfall — fungerte · delvis · ikke — og en valgfri\n * setning ≤ 140. Én per oppgave; et gjentak er 409 `task_already_completed`. En egen\n * innsending kan henge ved. Teller `task_completed` med utfallet, aldri teksten.\n */\n completeTask(taskId: string, completion: TaskCompletionCreate): Promise<TaskCompletionView>;\n /**\n * «Hvordan gikk det?» på en utsendt oppfølging fra `list().pendingFollowUps`: de samme\n * tre valgene og en valgfri setning ≤ 140. Bare `hvordan_gikk_det` og `sjekkpunkt` tar\n * svar — en påminnelse eller et tilbud om utgang gir 409 `follow_up_not_answerable`.\n * Engangs (409 `follow_up_already_answered`). Teller `followup_answered`.\n */\n respond(followUpId: string, response: FollowUpResponseCreate): Promise<void>;\n };\n\n readonly attachments: {\n /**\n * Laster opp ett maskert skjermbilde til en innsending som alt er lagret:\n * presign → PUT til lagringen → complete. Bruk `capture({ attachment })` i\n * stedet når teksten og bildet sendes sammen — da håndteres DD-42 for deg.\n * Plattformen verifiserer og re-enkoder etterpå; `processedAt` er satt når\n * det er gjort.\n */\n upload(submissionId: string, attachment: AttachmentInput): Promise<AttachmentView>;\n };\n\n readonly queue: {\n pending(): Promise<QueuedSubmission[]>;\n /** Sendes ellers automatisk når widgeten åpnes. Aldri ved oppstart (DD-41). */\n flush(): Promise<FlushResult>;\n };\n\n /** Mønstervarsel (DD-46). Returnerer funn — fjerner aldri noe. */\n scanText(text: string): PatternFinding[];\n\n /** Emitter en tragt-hendelse. Brukes av UI-laget for `widget_opened` og `track_selected`. */\n track(event: TelemetryEvent): void;\n\n /** Åpner widgeten. Krever `@innspel/react-native`. */\n openFeedback(options?: OpenFeedbackOptions): Promise<void>;\n\n /** Registrerer visningen. Kalles av `@innspel/react-native`, ikke av verten. */\n registerPresenter(presenter: Presenter): void;\n}\n\nfunction krev(betingelse: boolean, felt: string, hva: string): void {\n if (!betingelse) throw new InnspelConfigError(felt, hva);\n}\n\nfunction validerOpsjoner(o: InnspelOptions): void {\n krev(o !== null && typeof o === 'object', 'options', 'mangler — init() tar ett objekt');\n krev(\n typeof o.baseUrl === 'string' && o.baseUrl.length > 0,\n 'baseUrl',\n 'mangler. Sett plattformens API-rot, f.eks. https://api.innspel.example — SDK-et gjetter aldri hvor dataene havner',\n );\n krev(\n typeof o.tenantKey === 'string' && o.tenantKey.length > 0,\n 'tenantKey',\n 'mangler. Den offentlige SDK-nøkkelen finner du i panelet under Innstillinger → Produkter',\n );\n krev(\n erHeaderTrygg(o.tenantKey),\n 'tenantKey',\n 'har tegn som ikke kan stå i en HTTP-header (mellomrom, linjeskift eller tegn utenfor ASCII). Har du kopiert en placeholder med «…» i, bytt den mot den ekte nøkkelen fra panelet',\n );\n krev(\n o.identityProvider === null || typeof o.identityProvider === 'function',\n 'identityProvider',\n 'må være en funksjon som gir et feedback-token, eller null for anonym modus. Anonym modus er et eksplisitt valg, aldri en glemt opsjon',\n );\n\n const s = o.storage as Partial<InnspelOptions['storage']> | undefined;\n krev(s !== null && typeof s === 'object', 'storage', 'mangler. Offline-køen lagres her (DD-41)');\n for (const metode of ['get', 'set', 'remove'] as const) {\n krev(typeof s?.[metode] === 'function', `storage.${metode}`, 'mangler eller er ikke en funksjon');\n }\n\n validerKontekst(o.context ?? {}, 'context', true);\n\n if (o.textMaxLength !== undefined) {\n krev(\n o.textMaxLength === 140 || o.textMaxLength === 280,\n 'textMaxLength',\n 'må være 140 eller 280 — kontrakten har to verdier, og 140 er den som gjelder ved minorsPresent',\n );\n }\n if (o.minTextLength !== undefined) {\n krev(\n Number.isInteger(o.minTextLength) && o.minTextLength >= 1,\n 'minTextLength',\n 'må være et heltall ≥ 1 (DD-44)',\n );\n }\n if (o.telemetry !== undefined) {\n krev(\n typeof o.telemetry?.emit === 'function',\n 'telemetry.emit',\n 'mangler eller er ikke en funksjon',\n );\n }\n if (o.connectivity !== undefined) {\n krev(\n typeof o.connectivity?.isOnline === 'function',\n 'connectivity.isOnline',\n 'mangler eller er ikke en funksjon. Gi et objekt med isOnline() og valgfri subscribe(), eller utelat opsjonen — se docs/sdk/README.md, «Nettstatus»',\n );\n krev(\n o.connectivity.subscribe === undefined || typeof o.connectivity.subscribe === 'function',\n 'connectivity.subscribe',\n 'er valgfri, men må være en funksjon som gir en avmelding tilbake',\n );\n }\n}\n\n/** Oversetter et feilsvar fra plattformen til {@link InnspelApiError}. */\nfunction tilApiFeil(status: number, kropp: unknown, response?: Response): InnspelApiError {\n const body = (kropp ?? {}) as Partial<ApiErrorBody>;\n const kode = (body.code ?? 'unknown') as ErrorCode | 'unknown';\n const retryAfter = Number(response?.headers.get('retry-after') ?? NaN);\n return new InnspelApiError(\n status,\n kode,\n body.message ?? `Kallet feilet med status ${status}.`,\n Number.isFinite(retryAfter) ? retryAfter : undefined,\n );\n}\n\n/**\n * Setter opp SDK-et. Validerer opsjonene ved kjøretid og kaster umiddelbart med\n * feltnavnet ved feil bruk — typer stopper ikke en JavaScript-vert eller en feil\n * `.env` (tech-decisions.md, «SDK — dokumentasjon og utvikleropplevelse»).\n *\n * Kaller ingenting og sender ingenting: køen tømmes ALDRI ved oppstart (DD-41).\n *\n * @example\n * ```ts\n * const innspel = init({\n * baseUrl: 'https://api.innspel.example',\n * tenantKey: 'ik_pub_xxxxxxxx',\n * identityProvider: hentFeedbackToken, // eller null = anonym\n * storage,\n * context: { platform: 'ios', appVersion: '1.4.2' },\n * });\n * ```\n */\nexport function init(options: InnspelOptions): InnspelClient {\n validerOpsjoner(options);\n\n const settings: ResolvedSettings = {\n // Strammest mulig til loadSettings() har svart: 140 / 10 / skjermbilde av er\n // verdiene ved minorsPresent (K18). Verten kan overstyre startverdiene, men\n // det leietakeren har satt i panelet vinner når konfigurasjonen er hentet.\n textMaxLength: options.textMaxLength ?? 140,\n minTextLength: options.minTextLength ?? 10,\n screenshotsEnabled: options.screenshotsEnabled ?? false,\n };\n\n const kontekst = slåSammenKontekst(options.context, undefined, VERSJON);\n const telemetri = options.telemetry ?? noopTelemetri;\n const kø = new Ko(options.storage);\n const anonym = options.identityProvider === null;\n\n /**\n * `fetch` med nettverksfeilene merket. Den genererte klienten fanger det fetch\n * kaster og svarer uten `response`; merket er det eneste som skiller «nettet er\n * nede» fra en feil i vår egen kode. Vertens fetch slås opp ved hvert kall.\n */\n const nett = ((input: Request) =>\n (options.fetch ?? fetch)(input).catch((e: unknown) => {\n throw new NettverksFeil(String(e));\n })) as typeof fetch;\n\n const klient: Client = createClient(createConfig({ baseUrl: options.baseUrl, fetch: nett }));\n\n let presenter: Presenter | null = null;\n\n /** Headere for ett kall. Tokenet hentes friskt hver gang — aldri fra disk (K20). */\n async function headere(): Promise<Record<string, string>> {\n const h: Record<string, string> = { 'X-Innspel-Tenant-Key': options.tenantKey };\n const token = await hentToken(options.identityProvider);\n if (token) h['Authorization'] = `Bearer ${token}`;\n return h;\n }\n\n /**\n * Tidsgrense for ett kall. React Native polyfyller `AbortSignal` uten\n * `AbortSignal.timeout`, og Expo legger den ikke til — der er det en egen\n * `AbortController` med timer, ryddet når kallet er ferdig.\n */\n async function medTidsgrense<T>(kall: (signal: AbortSignal) => Promise<T>): Promise<T> {\n const ms = options.timeoutMs ?? STANDARD_TIMEOUT_MS;\n if (typeof AbortSignal.timeout == 'function') return kall(AbortSignal.timeout(ms));\n const kontroll = new AbortController();\n const timer = setTimeout(() => kontroll.abort(), ms);\n try {\n return await kall(kontroll.signal);\n } finally {\n clearTimeout(timer);\n }\n }\n\n /**\n * Kjører et kall og prøver ÉN gang til ved `feedback_token_expired`.\n *\n * Kontrakten skiller bevisst `expired` fra `invalid`: den første er ventet og\n * håndteres her, den andre er en utviklerfeil i vertens token-endepunkt og\n * skal vises, ikke skjules.\n */\n async function medToken<T>(\n kall: (h: Record<string, string>, s: AbortSignal) => Promise<{ data?: T; error?: unknown; response: Response }>,\n ): Promise<T> {\n // Hvert forsøk får egen tidsgrense. Uten svar er feilen det fetch kastet\n // (NettverksFeil) eller en feil i koden før fetch — begge kastes som de er.\n const forsøk = async () => {\n const h = await headere();\n const r = await medTidsgrense((s) => kall(h, s));\n if (!r.response) throw r.error;\n return r;\n };\n let res = await forsøk();\n if (res.response.status === 401) {\n const feil = tilApiFeil(401, res.error, res.response);\n if (feil.code === 'feedback_token_expired' && !anonym) {\n res = await forsøk();\n }\n }\n if (!res.response.ok) throw tilApiFeil(res.response.status, res.error, res.response);\n return res.data as T;\n }\n\n /** Tokenet kommer fra leietakerens kanal (DD-12); en tom streng er en feil i vertens kobling, ikke et kall. */\n function krevInvitasjonstoken(token: string): void {\n if (typeof token !== 'string' || token.length === 0) {\n throw new InnspelConfigError(\n 'invitationToken',\n 'mangler — det er engangs-tokenet leietakeren sendte i sin egen kanal (dyplenke, varsel eller e-post)',\n );\n }\n }\n\n function krevToken(): void {\n if (anonym) {\n throw new InnspelApiError(\n 401,\n 'feedback_token_required',\n 'Anonym modus har ingen «mine innspill» — det finnes ingen identitet å slå opp.',\n );\n }\n }\n\n async function sendNå(\n input: CaptureInput,\n clientRef: string,\n kontekstForKall: ContextInput & { sdkVersion: string },\n ): Promise<SubmissionStatusView> {\n const body: Record<string, unknown> = {\n type: input.type,\n text: input.text,\n context: kontekstForKall,\n clientRef,\n };\n if (input.programId !== undefined) body['programId'] = input.programId;\n if (input.taskId !== undefined) body['taskId'] = input.taskId;\n if (input.type === 'feil') {\n if (input.correlation !== undefined) body['correlation'] = input.correlation;\n if (input.relatedKnownIssueId !== undefined) {\n body['relatedKnownIssueId'] = input.relatedKnownIssueId;\n }\n }\n\n return medToken<SubmissionStatusView>((h, s) =>\n ingestSubmissionsCreate({\n client: klient,\n headers: h,\n signal: s,\n body: body as never,\n }) as never,\n );\n }\n\n /**\n * Presign → PUT → complete. Bildet går rett til lagringen med nøyaktig\n * headerne presign ga; tenantKey og token følger aldri med dit.\n */\n async function lastOppVedlegg(submissionId: string, vedlegg: AttachmentInput): Promise<AttachmentView> {\n const presign = await medToken<AttachmentPresign>((h, s) =>\n ingestAttachmentsPresign({\n client: klient,\n headers: h,\n signal: s,\n body: {\n submissionId,\n mime: vedlegg.mime,\n bytes: byteLengde(vedlegg.body),\n width: vedlegg.width,\n height: vedlegg.height,\n },\n }) as never,\n );\n\n await medTidsgrense((s) => lastOppTilLagring(nett, presign, vedlegg.body, s));\n\n return medToken<AttachmentView>((h, s) =>\n ingestAttachmentsComplete({\n client: klient,\n headers: h,\n signal: s,\n path: { id: presign.attachmentId },\n }) as never,\n );\n }\n\n /**\n * Tømmer køen med et ferskt token per rad. Delt av og\n * — de to stedene DD-41 sier køen skal tømmes.\n */\n const flushKø = (): Promise<FlushResult> =>\n flushKo(\n kø,\n (rad) => sendNå({ type: rad.type, text: rad.text } as CaptureInput, rad.clientRef, kontekst),\n telemetri,\n );\n\n // Nettet tilbake → køen tømmes. Aldri ved oppstart (DD-41): bare på en hendelse verten melder.\n options.connectivity?.subscribe?.((online) => {\n if (online) void flushKø().catch(() => undefined);\n });\n\n const innspel: InnspelClient = {\n version: VERSJON,\n isAnonymous: anonym,\n connectivity: options.connectivity ?? null,\n settings,\n context: kontekst,\n\n async loadSettings() {\n try {\n const cfg = await medToken<ClientConfig>((h, s) =>\n ingestConfigGet({ client: klient, headers: h, signal: s }) as never,\n );\n // Bare det som faktisk kom: en fake eller en gammel plattform kan svare\n // med et delvis objekt, og da står det klienten alt har.\n if (cfg?.textMaxLength === 140 || cfg?.textMaxLength === 280) settings.textMaxLength = cfg.textMaxLength;\n if (typeof cfg?.minTextLength === 'number' && cfg.minTextLength >= 1) settings.minTextLength = cfg.minTextLength;\n if (typeof cfg?.screenshotsEnabled === 'boolean') settings.screenshotsEnabled = cfg.screenshotsEnabled;\n if (typeof cfg?.privacyUrl === 'string' && cfg.privacyUrl) settings.privacyUrl = cfg.privacyUrl;\n } catch {\n // Konfigurasjonen er et tilbud (wireframe 2c-prinsippet): svarer den ikke,\n // står de strammeste verdiene, og innsenderen kan fortsatt melde.\n }\n return settings;\n },\n\n async capture(input) {\n const tekst = input.text ?? '';\n if (tekst.length < settings.minTextLength) {\n throw new InnspelConfigError(\n 'text',\n `er ${tekst.length} tegn. Send-knappen skal være inaktiv under minst ${settings.minTextLength} tegn (DD-44)`,\n );\n }\n if (tekst.length > settings.textMaxLength) {\n throw new InnspelConfigError(\n 'text',\n `er ${tekst.length} tegn, over leietakerens grense på ${settings.textMaxLength}`,\n );\n }\n if (input.context) validerKontekst(input.context, 'capture.context', false);\n // Vedlegget valideres FØR teksten sendes: et bilde over grensene er en\n // utviklerfeil i fangsten, og skal feile før noe er lagret.\n if (input.attachment) validerVedlegg(input.attachment);\n\n const clientRef = input.clientRef ?? nyClientRef();\n const kontekstForKall = slåSammenKontekst(options.context, input.context, VERSJON);\n\n let submission;\n try {\n submission = await sendNå(input, clientRef, kontekstForKall);\n } catch (e) {\n if (e instanceof InnspelApiError) {\n telemetri.emit({ name: 'submission_failed', reason: e.code });\n throw e;\n }\n // En feil i koden køes ikke: den ville sett ut som «Ingen nett» med nett\n // på og aldri blitt tømt. Teksten står i vertens felt.\n if (!(e instanceof NettverksFeil)) throw e;\n // Nettverksfeil: teksten mistes aldri. Kun tekst køes — aldri et\n // skjermbilde (rapport 3, kap. 5).\n await kø.leggTil({\n clientRef,\n type: input.type,\n text: tekst,\n queuedAt: new Date().toISOString(),\n });\n telemetri.emit({\n name: 'submission_sent',\n type: input.type,\n hasAttachment: false,\n offlineQueued: true,\n });\n // Et skjermbilde køes aldri (DD-41): det ble forkastet, og UI-et skal si det.\n return input.attachment\n ? { status: 'queued', clientRef, attachment: { status: 'dropped' } }\n : { status: 'queued', clientRef };\n }\n\n // DD-42: teksten er lagret. Bildet lastes opp i egen forespørsel og kan\n // feile alene — innsendingen står uansett, og kvitteringen sier hva som skjedde.\n let attachment: AttachmentOutcome | undefined;\n if (input.attachment) {\n try {\n attachment = { status: 'uploaded', attachment: await lastOppVedlegg(submission.id, input.attachment) };\n } catch (e) {\n attachment = { status: 'failed', error: e instanceof Error ? e : new Error(String(e)) };\n }\n }\n\n telemetri.emit({\n name: 'submission_sent',\n type: input.type,\n hasAttachment: attachment?.status === 'uploaded',\n offlineQueued: false,\n });\n return attachment ? { status: 'sent', submission, attachment } : { status: 'sent', submission };\n },\n\n knownIssues: {\n async for(query = {}) {\n try {\n const kort = await medToken<KnownIssueCard[]>((h, s) =>\n ingestKnownIssuesList({\n client: klient,\n headers: h,\n signal: s,\n query: {\n ...(query.screen !== undefined ? { screen: query.screen } : {}),\n ...(query.version !== undefined ? { version: query.version } : {}),\n platform: query.platform ?? kontekst.platform,\n },\n }) as never,\n );\n const liste = kort ?? [];\n telemetri.emit({ name: 'known_issue_shown', count: liste.length });\n return liste;\n } catch {\n // «Treffene er et tilbud, aldri en sperre» (wireframe 2c): svarer ikke\n // sjekken, hoppes den over — rett til feltet, ingen melding.\n return [];\n }\n },\n\n async confirm(knownIssueId) {\n const res = await medToken<SubmissionStatusView>((h, s) =>\n ingestKnownIssuesConfirm({\n client: klient,\n headers: h,\n signal: s,\n path: { id: knownIssueId },\n body: { context: kontekst } as never,\n }) as never,\n );\n telemetri.emit({ name: 'known_issue_confirmed' });\n return res;\n },\n },\n\n subjects: {\n async submissions() {\n krevToken();\n\n const ventende: MySubmission[] = (await kø.les()).map((r) => ({\n pending: true as const,\n clientRef: r.clientRef,\n type: r.type,\n text: r.text,\n queuedAt: r.queuedAt,\n }));\n\n let sendte: SubmissionStatusView[] | undefined;\n try {\n sendte = await medToken<SubmissionStatusView[]>((h, s) =>\n ingestSubmissionsListMine({ client: klient, headers: h, signal: s }) as never,\n );\n } catch (e) {\n // En ekte API-feil skjules aldri — 401 og 429 skal fram.\n if (!(e instanceof NettverksFeil)) throw e;\n // Nettverksfeil er noe annet: køen er LOKAL, og den er hele poenget\n // med «Mine innspill» offline (DD-41). At serveren er utilgjengelig\n // skal ikke skjule raden som venter på nett — det er nøyaktig da\n // innsenderen trenger å se den.\n return ventende;\n }\n\n telemetri.emit({ name: 'status_viewed' });\n return [...ventende, ...(sendte ?? [])];\n },\n\n async status(submissionId) {\n krevToken();\n return medToken<SubmissionStatusView>((h, s) =>\n ingestSubmissionsStatus({\n client: klient,\n headers: h,\n signal: s,\n path: { id: submissionId },\n }) as never,\n );\n },\n },\n\n programs: {\n async list() {\n krevToken();\n return medToken<MyPrograms>((h, s) =>\n ingestProgramsListMine({ client: klient, headers: h, signal: s }) as never,\n );\n },\n\n async accept(invitationToken) {\n krevInvitasjonstoken(invitationToken);\n krevToken();\n const svar = await medToken<ParticipationView>((h, s) =>\n ingestProgramsAccept({\n client: klient,\n headers: h,\n signal: s,\n path: { token: invitationToken },\n }) as never,\n );\n telemetri.emit({ name: 'invitation_accepted' });\n return svar;\n },\n\n async decline(invitationToken) {\n krevInvitasjonstoken(invitationToken);\n krevToken();\n await medToken<void>((h, s) =>\n ingestProgramsDecline({\n client: klient,\n headers: h,\n signal: s,\n path: { token: invitationToken },\n }) as never,\n );\n telemetri.emit({ name: 'invitation_declined' });\n },\n\n async withdraw(participationId) {\n if (typeof participationId !== 'string' || participationId.length === 0) {\n throw new InnspelConfigError('participationId', 'mangler — bruk id fra deltakelsen i programs.list()');\n }\n krevToken();\n return medToken<ParticipationView>((h, s) =>\n ingestProgramsWithdraw({\n client: klient,\n headers: h,\n signal: s,\n path: { id: participationId },\n }) as never,\n );\n },\n\n async completeTask(taskId, completion) {\n if (typeof taskId !== 'string' || taskId.length === 0) {\n throw new InnspelConfigError('taskId', 'mangler — bruk id fra program.tasks i programs.list()');\n }\n validerUtfall(completion);\n krevToken();\n const svar = await medToken<TaskCompletionView>((h, s) =>\n ingestProgramsCompleteTask({\n client: klient,\n headers: h,\n signal: s,\n path: { id: taskId },\n body: completion,\n }) as never,\n );\n telemetri.emit({ name: 'task_completed', outcome: completion.outcome });\n return svar;\n },\n\n async respond(followUpId, response) {\n if (typeof followUpId !== 'string' || followUpId.length === 0) {\n throw new InnspelConfigError('followUpId', 'mangler — bruk id fra pendingFollowUps i programs.list()');\n }\n validerUtfall(response);\n krevToken();\n await medToken<void>((h, s) =>\n ingestProgramsRespond({\n client: klient,\n headers: h,\n signal: s,\n path: { id: followUpId },\n body: response,\n }) as never,\n );\n telemetri.emit({ name: 'followup_answered' });\n },\n },\n\n attachments: {\n async upload(submissionId, attachment) {\n if (typeof submissionId !== 'string' || submissionId.length === 0) {\n throw new InnspelConfigError('submissionId', 'mangler — bruk id fra innsendingen capture() ga');\n }\n validerVedlegg(attachment);\n return lastOppVedlegg(submissionId, attachment);\n },\n },\n\n queue: {\n pending: () => kø.les(),\n flush: flushKø,\n },\n\n scanText,\n\n track: (event) => telemetri.emit(event),\n\n async openFeedback(åpneOpsjoner) {\n if (!presenter) {\n throw new InnspelConfigError(\n 'openFeedback',\n 'krever en visning. @innspel/core har ingen UI — installer @innspel/react-native og pakk appen i <InnspelProvider>. Trenger du å sende uten widget, bruk capture()',\n );\n }\n // Køen tømmes når widgeten åpnes — aldri ved oppstart (DD-41).\n await flushKø();\n await presenter.open(åpneOpsjoner);\n },\n\n registerPresenter(p) {\n presenter = p;\n },\n };\n\n return innspel;\n}\n","/**\n * Geometrien bak maskeringen (DD-39, DD-40) — ren TypeScript uten UI, så den\n * kan testes her og brukes likt av `@innspel/react-native` og `@innspel/web`.\n *\n * Alt er rektangler i BILDETS pikselkoordinater. UI-laget tegner dem som\n * heldekkende flater over forhåndsvisningen og rekomponerer bitmapen; det som\n * står her avgjør bare HVOR flatene ligger. Private views (DD-39) er rektangler\n * som UI-et aldri lar brukeren fjerne — den regelen håndheves der, ikke her,\n * fordi den handler om hvem som la rektangelet, ikke om geometri.\n */\n\nexport interface MaskPoint {\n x: number;\n y: number;\n}\n\nexport interface MaskRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Ett fingerstrøk («Tegn over», DD-40) til rektangler: en kvadratisk flate per\n * punkt, og én per mellomrom mellom to punkter, så strøket er tett selv om\n * fingeren beveget seg fort. Alle klippes til bildet.\n */\nexport function strokTilRekter(punkter: readonly MaskPoint[], penselBredde: number, bilde: { width: number; height: number }): MaskRect[] {\n if (penselBredde <= 0 || punkter.length === 0) return [];\n const halv = penselBredde / 2;\n const ut: MaskRect[] = [];\n\n const legg = (p: MaskPoint) => {\n const r = klipp({ x: p.x - halv, y: p.y - halv, width: penselBredde, height: penselBredde }, bilde);\n if (r) ut.push(r);\n };\n\n legg(punkter[0]!);\n for (let i = 1; i < punkter.length; i++) {\n const a = punkter[i - 1]!;\n const b = punkter[i]!;\n const avstand = Math.hypot(b.x - a.x, b.y - a.y);\n // Fyll gapet med mellomliggende kvadrater når fingeren beveget seg mer enn\n // en halv penselbredde — ellers blir strøket en rekke løse prikker.\n const steg = Math.max(1, Math.ceil(avstand / halv));\n for (let s = 1; s <= steg; s++) {\n legg({ x: a.x + ((b.x - a.x) * s) / steg, y: a.y + ((b.y - a.y) * s) / steg });\n }\n }\n return ut;\n}\n\n/** «Masker felt» (DD-40): ett trykk legger en boks sentrert på punktet. */\nexport function trykkTilRekt(punkt: MaskPoint, boks: { width: number; height: number }, bilde: { width: number; height: number }): MaskRect | null {\n return klipp({ x: punkt.x - boks.width / 2, y: punkt.y - boks.height / 2, width: boks.width, height: boks.height }, bilde);\n}\n\n/**\n * Klipper et rektangel til bildet. Null når ingenting er igjen — et rektangel\n * helt utenfor bildet skal ikke tegnes, og heller ikke telles som en maskering.\n */\nexport function klipp(r: MaskRect, bilde: { width: number; height: number }): MaskRect | null {\n const x1 = Math.max(0, r.x);\n const y1 = Math.max(0, r.y);\n const x2 = Math.min(bilde.width, r.x + r.width);\n const y2 = Math.min(bilde.height, r.y + r.height);\n if (x2 <= x1 || y2 <= y1) return null;\n return { x: x1, y: y1, width: x2 - x1, height: y2 - y1 };\n}\n\n/**\n * Skalerer et rektangel fra ett koordinatsystem til et annet — typisk fra\n * skjermpunkter (der fingeren var) til bildepiksler (der masken skal ligge).\n * Rundes UTOVER: en maske skal aldri bli en piksel for liten.\n */\nexport function skaler(r: MaskRect, fra: { width: number; height: number }, til: { width: number; height: number }): MaskRect {\n const sx = til.width / fra.width;\n const sy = til.height / fra.height;\n const x = Math.floor(r.x * sx);\n const y = Math.floor(r.y * sy);\n return {\n x,\n y,\n width: Math.ceil((r.x + r.width) * sx) - x,\n height: Math.ceil((r.y + r.height) * sy) - y,\n };\n}\n\n/** Om et punkt ligger i et av rektanglene — brukes for «trykk på en maske for å angre den». */\nexport function treffer(punkt: MaskPoint, r: MaskRect): boolean {\n return punkt.x >= r.x && punkt.x < r.x + r.width && punkt.y >= r.y && punkt.y < r.y + r.height;\n}\n\n/**\n * Om rektanglene dekker hele bildet. UI-et bruker det til å si «alt er\n * maskert» — da er det ingenting å sende, og «Fjern bildet» er det ærlige valget.\n */\nexport function dekkerAlt(rekter: readonly MaskRect[], bilde: { width: number; height: number }): boolean {\n return rekter.some((r) => r.x <= 0 && r.y <= 0 && r.x + r.width >= bilde.width && r.y + r.height >= bilde.height);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/feil.ts","../src/identitet.ts","../src/flush.ts","../src/ko.ts","../src/kontekst.ts","../src/monster.ts","../src/uuid.ts","../src/vedlegg.ts","../src/klient.ts","../src/maskering.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ErrorCode } from './api.js';\n\n/** Prefikset alle utviklerrettede meldinger fra SDK-et bærer. */\nexport const PREFIKS = '[innspel]';\n\n/**\n * En HTTP-headerverdi må være en ByteString: synlige ASCII-tegn, ingen\n * mellomrom, linjeskift eller tegn over U+00FF. Brytes det, kaster\n * `new Request(...)` en `TypeError` — og den er umulig å skille fra «nettet er\n * nede», så en utviklerfeil ville sett ut som en innsending som venter på nett.\n *\n * Funnet ved å kjøre quickstarten i et tomt prosjekt: README-placeholderen\n * `ik_pub_…` inneholder U+2026.\n */\nexport function erHeaderTrygg(verdi: string): boolean {\n return /^[\\x21-\\x7e]+$/.test(verdi);\n}\n\n/**\n * Utviklerfeil: opsjoner som er feil eller mangler, kontekstfelter utenfor\n * hvitelisten, tekst utenfor grensene. Kastes umiddelbart og navngir feltet —\n * aldri en stille tom widget (tech-decisions.md, «SDK — dokumentasjon og\n * utvikleropplevelse»).\n */\nexport class InnspelConfigError extends Error {\n override readonly name = 'InnspelConfigError';\n /** Feltet som er galt, slik det heter i `init`-opsjonene. */\n readonly field: string;\n\n constructor(field: string, hva: string, hvor = 'README.md') {\n super(`${PREFIKS} ${field}: ${hva}. Se ${hvor}.`);\n this.field = field;\n }\n}\n\n/**\n * Feil fra plattformen. Forgren på `code`, aldri på `message` — meldingen er\n * for mennesker og kan endres uten varsel (contracts/models/common.tsp).\n */\nexport class InnspelApiError extends Error {\n override readonly name = 'InnspelApiError';\n readonly code: ErrorCode | 'unknown';\n readonly status: number;\n /** Sekunder til neste forsøk, fra Retry-After. Kun ved 429. */\n readonly retryAfter: number | undefined;\n\n constructor(status: number, code: ErrorCode | 'unknown', message: string, retryAfter?: number) {\n super(message);\n this.status = status;\n this.code = code;\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Intern, eksporteres ikke: `fetch` selv kastet — ingen forbindelse, eller\n * tidsgrensen avbrøt kallet. Bare denne legger en innsending i offline-køen. Alt\n * annet uten svar er en feil i koden og skal synes, ikke se ut som «Ingen nett».\n */\nexport class NettverksFeil extends Error {}\n\n/**\n * Offline-køen er full. Taket er 30 (DD-41), og den eldste beholdes: det første\n * innspillet er like mye verdt som det siste, og å kaste det stille ville brutt\n * løftet om at teksten aldri mistes.\n */\nexport class InnspelQueueFullError extends Error {\n override readonly name = 'InnspelQueueFullError';\n readonly code = 'queue_full' as const;\n /** Tekst som kan vises til innsenderen. Køen skal være synlig, ikke stille. */\n readonly userMessage: string;\n\n constructor(tak: number) {\n super(`${PREFIKS} offline-køen er full (${tak}).`);\n this.userMessage = `Du har ${tak} innspill som venter på nett. Send dem før du skriver flere — de sendes automatisk når du er på nett igjen.`;\n }\n}\n","import { erHeaderTrygg, PREFIKS } from './feil.js';\nimport type { IdentityProvider } from './typer.js';\n\n/**\n * Henter et ferskt feedback-token fra verten.\n *\n * Tokenet lagres ALDRI (K20, DD-41): det er gyldig i høyst 15 minutter, og ved\n * en flush av offline-køen er det gamle utløpt for lengst. Kjernen ber om et\n * nytt hver gang den trenger ett.\n *\n * Kaster vertens funksjon, eller returnerer den `null`, går kallet anonymt.\n * Innsenderen skal kunne melde fra selv om vertens innlogging er nede — men det\n * er en utviklerfeil, så den går til `console.error` med `[innspel]`-prefiks\n * (tech-decisions.md, «SDK — dokumentasjon og utvikleropplevelse»).\n */\nexport async function hentToken(\n provider: IdentityProvider | null,\n): Promise<string | null> {\n if (provider === null) return null;\n\n try {\n const token = await provider();\n if (typeof token !== 'string' || token.length === 0) return null;\n\n // Et token som ikke kan bli en headerverdi ville fått Request-byggingen til\n // å kaste en TypeError, og den er ikke til å skille fra «nettet er nede» —\n // innsendingen ville havnet i offline-køen og sett ut som om den venter på\n // nett. Feil i token-endepunktet skal være synlig som nettopp det.\n if (!erHeaderTrygg(token)) {\n console.error(\n `${PREFIKS} identityProvider ga et token med tegn som ikke kan stå i en HTTP-header (mellomrom, linjeskift eller tegn utenfor ASCII). Et JWT er base64url og har ingen slike. Innsendingen går anonymt — se docs/sdk/README.md.`,\n );\n return null;\n }\n\n return token;\n } catch (e) {\n console.error(\n `${PREFIKS} identityProvider kastet. Innsendingen går anonymt og kan ikke følges opp. Rett feilen i token-endepunktet — se docs/sdk/README.md.`,\n e,\n );\n return null;\n }\n}\n","import { InnspelApiError } from './feil.js';\nimport type { Ko } from './ko.js';\nimport type { FlushResult, QueuedSubmission, Telemetry } from './typer.js';\n\n/**\n * Tømmer offline-køen. Kalles når widgeten åpnes eller når appen får nett med\n * widgeten åpen — **aldri ved oppstart** (DD-41).\n *\n * Hver rad sendes med et FERSKT token: det gamle er utløpt for lengst (exp ≤ 15\n * min). Det er `send` som henter det, én gang per rad.\n *\n * To utfall skiller seg:\n * - **4xx** — plattformen avviste kroppen. Den blir aldri gyldig, så raden\n * forkastes i stedet for å prøves i evighet. Innsenderen skal ikke ha en rad\n * som står og «venter på nett» for alltid.\n * - **nettverksfeil** — nettet er nede igjen. Resten står, og vi stopper: de\n * neste radene ville feilet på samme måte, og hvert forsøk koster rate limit.\n */\nexport async function flushKo(\n kø: Ko,\n send: (rad: QueuedSubmission) => Promise<unknown>,\n telemetri: Telemetry,\n): Promise<FlushResult> {\n const rader = await kø.les();\n let sent = 0;\n let failed = 0;\n\n for (const rad of rader) {\n try {\n await send(rad);\n await kø.fjern(rad.clientRef);\n sent++;\n } catch (e) {\n if (e instanceof InnspelApiError && e.status >= 400 && e.status < 500) {\n await kø.fjern(rad.clientRef);\n failed++;\n telemetri.emit({ name: 'submission_failed', reason: e.code });\n continue;\n }\n break;\n }\n }\n\n return { sent, failed, remaining: await kø.antall() };\n}\n","import { InnspelQueueFullError } from './feil.js';\nimport type { InnspelStorage, QueuedSubmission } from './typer.js';\n\n/**\n * DD-41 — «Offline-køen er maks 30, tømmes aldri ved oppstart, og er synlig.»\n *\n * Kilde: Sentry `maxQueueSize` 30 og `flushAtStartup` false; Shake «Feedback\n * pending sync» er den eneste leverandøren som viser tilstanden til brukeren.\n * Kvitteringen i DD-07 kan ikke love svar på noe som ikke er sendt — derfor er\n * køen synlig i «Mine innspill», ikke en usynlig bakgrunnsjobb.\n *\n * Rate limit-tallet per subject i M1.1 er satt til 60 nettopp for at en full kø\n * på 30 skal kunne tømmes på ett minutt (tech-decisions.md, «M1.1»).\n */\nexport const KO_TAK = 30;\n\nconst NØKKEL = 'innspel:queue';\n\nexport class Ko {\n readonly #storage: InnspelStorage;\n\n constructor(storage: InnspelStorage) {\n this.#storage = storage;\n }\n\n /**\n * Leser køen. En ødelagt rad i lagringen gir tom kø, ikke et unntak: en\n * halvskrevet JSON etter at appen ble drept skal ikke hindre innsenderen i å\n * melde fra på nytt.\n */\n async les(): Promise<QueuedSubmission[]> {\n const rå = await this.#storage.get(NØKKEL);\n if (!rå) return [];\n try {\n const parset: unknown = JSON.parse(rå);\n return Array.isArray(parset) ? (parset as QueuedSubmission[]) : [];\n } catch {\n return [];\n }\n }\n\n async #skriv(rader: QueuedSubmission[]): Promise<void> {\n if (rader.length === 0) {\n await this.#storage.remove(NØKKEL);\n return;\n }\n await this.#storage.set(NØKKEL, JSON.stringify(rader));\n }\n\n /**\n * Legger en innsending bakerst.\n *\n * Ved fullt tak kastes {@link InnspelQueueFullError} — den eldste beholdes.\n * Å kaste den eldste ville vært stille tap av noe innsenderen tror er sendt.\n */\n async leggTil(rad: QueuedSubmission): Promise<void> {\n const rader = await this.les();\n if (rader.length >= KO_TAK) throw new InnspelQueueFullError(KO_TAK);\n rader.push(rad);\n await this.#skriv(rader);\n }\n\n async fjern(clientRef: string): Promise<void> {\n const rader = await this.les();\n await this.#skriv(rader.filter((r) => r.clientRef !== clientRef));\n }\n\n async antall(): Promise<number> {\n return (await this.les()).length;\n }\n}\n","import { InnspelConfigError } from './feil.js';\nimport type { ContextInput, Platform } from './typer.js';\n\n/**\n * Den lukkede hvitelista (K5), som feltnavn. Listen er kilden både til\n * valideringen og til det som faktisk sendes — et felt som ikke står her kommer\n * aldri ut av kjernen, uansett hva verten fyller inn.\n *\n * `sdkVersion` står ikke her fordi den ikke kommer fra verten: kjernen setter\n * den selv, og en vert som prøver å overstyre den blir ignorert.\n */\nexport const KONTEKST_FELTER = [\n 'platform',\n 'appVersion',\n 'build',\n 'os',\n 'screen',\n 'locale',\n] as const;\n\nconst PLATTFORMER: readonly Platform[] = [\n 'ios',\n 'android',\n 'web',\n 'tvos',\n 'androidtv',\n 'tizen',\n 'webos',\n];\n\n/**\n * Sjekker et kontekstobjekt mot hvitelisten og kaster med feltnavnet ved avvik.\n *\n * Plattformen ville svart 400 `unknown_field` på det samme, men da har\n * innsenderen allerede skrevet ferdig. Kjernen feiler i stedet ved `init`, mens\n * utvikleren står i det (tech-decisions.md, «Feil bruk feiler høyt og tidlig»).\n *\n * @param kontekst Rå kontekst fra verten.\n * @param sti Feltnavnet i feilmeldingen — `context` fra `init`, ellers `capture`.\n * @param krevPlatform `platform` er påkrevd i `init`, valgfri i et enkeltkall\n * som bare legger på `screen`.\n */\nexport function validerKontekst(\n kontekst: Partial<ContextInput>,\n sti: string,\n krevPlatform: boolean,\n): void {\n if (kontekst === null || typeof kontekst !== 'object') {\n throw new InnspelConfigError(sti, 'må være et objekt med minst { platform }');\n }\n\n for (const nøkkel of Object.keys(kontekst)) {\n if (!(KONTEKST_FELTER as readonly string[]).includes(nøkkel)) {\n throw new InnspelConfigError(\n `${sti}.${nøkkel}`,\n `er ikke i kontekst-hvitelisten. Tillatt: ${KONTEKST_FELTER.join(', ')}. Lista er lukket (K5) — enhets-ID, IP og skjerminnhold hører ikke hjemme her`,\n );\n }\n }\n\n const plattform = kontekst.platform;\n if (krevPlatform && plattform === undefined) {\n throw new InnspelConfigError(`${sti}.platform`, 'er påkrevd');\n }\n if (plattform !== undefined && !PLATTFORMER.includes(plattform)) {\n throw new InnspelConfigError(\n `${sti}.platform`,\n `må være en av ${PLATTFORMER.join(', ')}`,\n );\n }\n}\n\n/**\n * Slår sammen konteksten fra `init` med det enkeltkallet legger på, og setter\n * `sdkVersion` til slutt så den ikke kan overstyres.\n *\n * Et felt som STÅR i kallets kontekst med verdien `undefined` eller `null`\n * FJERNES — det er «Fjern» i kontekstlinja (DD-05). Et felt som ikke står der,\n * beholdes fra `init`. Skillet er `in`, ikke `??`: før 0.2.1 fylte kjernen et\n * fjernet felt fra `init` igjen, og «Fjern» i widgeten var en løgn.\n */\nexport function slåSammenKontekst(\n base: ContextInput,\n påLagt: Partial<ContextInput> | undefined,\n sdkVersion: string,\n): ContextInput & { sdkVersion: string } {\n const ut: Record<string, unknown> = {};\n for (const felt of KONTEKST_FELTER) {\n const verdi = påLagt && felt in påLagt ? påLagt[felt] : base[felt];\n if (verdi !== undefined && verdi !== null) ut[felt] = verdi;\n }\n ut['sdkVersion'] = sdkVersion;\n return ut as unknown as ContextInput & { sdkVersion: string };\n}\n","import type { PatternFinding, PatternKind } from './typer.js';\n\n/**\n * DD-46 — mønstervarsel før sending, aldri stille redaksjon.\n *\n * Shake redigerer de samme mønstrene, men stille og kun i logger. Innspel har\n * ingen logger: teksten ER innspillet, og en stille endring ville gjort\n * innsenderen til usikker kilde på sin egen sak. Derfor returnerer denne\n * funksjonen FUNN. Den fjerner aldri noe — «Fjern» eller «Behold» er\n * innsenderens valg (DD-05).\n *\n * Regex i kjernen, ingen avhengighet (K19).\n */\n\ninterface Regel {\n kind: PatternKind;\n re: RegExp;\n /** Ekstra sjekk der formen alene gir for mange falske varsler. */\n gyldig?: (treff: string) => boolean;\n}\n\n/**\n * Luhn. Uten den varsles hvert 16-sifrede ordrenummer som kortnummer, og et\n * varsel som stemmer sjelden lærer folk å trykke «Behold» uten å lese.\n */\nfunction luhn(siffer: string): boolean {\n let sum = 0;\n let annenhver = false;\n for (let i = siffer.length - 1; i >= 0; i--) {\n let n = siffer.charCodeAt(i) - 48;\n if (n < 0 || n > 9) return false;\n if (annenhver) {\n n *= 2;\n if (n > 9) n -= 9;\n }\n sum += n;\n annenhver = !annenhver;\n }\n return sum % 10 === 0;\n}\n\nfunction gyldigIp(treff: string): boolean {\n const deler = treff.split('.');\n return deler.length === 4 && deler.every((d) => d.length <= 3 && Number(d) <= 255);\n}\n\nconst REGLER: Regel[] = [\n {\n kind: 'email',\n re: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}/g,\n },\n {\n // JWT-form først: tre base64url-segmenter. Fanger et feedback-token limt\n // inn fra en feilmelding — nøyaktig det innsenderen ikke bør sende.\n //\n // Siste segment krever bare 4 tegn. En ekte ES256-signatur er ~86, men et\n // token som er avkortet i en feilmelding er like uønsket i innspillsteksten,\n // og de to første segmentene på 16+ base64url-tegn hver gjør falske treff i\n // norsk prosa nesten umulige.\n kind: 'token',\n re: /\\b[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{4,}\\b|\\b(?:sk|pk|ghp|xox[abpr])[-_][A-Za-z0-9_-]{16,}\\b/g,\n },\n {\n kind: 'card',\n // 13–19 siffer med valgfrie mellomrom eller bindestrek mellom grupper.\n re: /\\b(?:\\d[ -]?){12,18}\\d\\b/g,\n gyldig: (t) => {\n const siffer = t.replace(/[^\\d]/g, '');\n return siffer.length >= 13 && siffer.length <= 19 && luhn(siffer);\n },\n },\n {\n kind: 'ip',\n re: /\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b/g,\n gyldig: gyldigIp,\n },\n {\n kind: 'phone',\n // Norsk form: 8 siffer, med eller uten +47/0047 og gruppering.\n re: /(?:\\+47|0047)?[ ]?(?:\\d[ ]?){8}(?![ ]?\\d)/g,\n gyldig: (t) => {\n const siffer = t.replace(/[^\\d]/g, '');\n const uten = siffer.replace(/^(?:47|0047)/, '');\n return uten.length === 8;\n },\n },\n];\n\n/**\n * Leter etter e-post, telefonnummer, kortnummer (Luhn-validert), IP-adresser og\n * token-lignende strenger i en innspillstekst.\n *\n * Rekkefølgen på reglene er bevisst: de spesifikke først, så et treff som\n * allerede er dekket av en sterkere regel ikke varsles to ganger. Et kortnummer\n * er ikke også et telefonnummer.\n *\n * @param text Teksten innsenderen har skrevet. Endres ikke.\n * @returns Funnene med posisjon, så verten kan markere dem i feltet. Tom liste\n * for en vanlig innsending.\n */\nexport function scanText(text: string): PatternFinding[] {\n const funn: PatternFinding[] = [];\n const opptatt: Array<[number, number]> = [];\n\n for (const regel of REGLER) {\n regel.re.lastIndex = 0;\n let treff: RegExpExecArray | null;\n while ((treff = regel.re.exec(text)) !== null) {\n const rå = treff[0];\n const trimmet = rå.trim();\n if (!trimmet) continue;\n\n const start = treff.index + rå.indexOf(trimmet);\n const end = start + trimmet.length;\n\n if (regel.gyldig && !regel.gyldig(trimmet)) continue;\n if (opptatt.some(([a, b]) => start < b && end > a)) continue;\n\n opptatt.push([start, end]);\n funn.push({ kind: regel.kind, match: trimmet, start, end });\n }\n }\n\n return funn.sort((a, b) => a.start - b.start);\n}\n","/**\n * `clientRef` — en tilfeldig UUID per INNSENDING, aldri per enhet eller\n * installasjon (K20, og kontraktens `SubmissionCreateBase.clientRef`). Den er\n * en idempotensnøkkel for offline-køen, ikke en identitet: to innsendinger fra\n * samme telefon deler den aldri.\n *\n * Bruker `crypto.randomUUID` der den finnes (Node, moderne nettlesere) og\n * faller tilbake til `Math.random` ellers — React Native har ingen WebCrypto\n * uten polyfill, og kjernen skal ikke kreve en (K19). Fallbacken er god nok:\n * nøkkelen er ikke en hemmelighet, og kollisjonsvinduet er én innsender i 24\n * timer.\n */\nexport function nyClientRef(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (typeof c?.randomUUID === 'function') return c.randomUUID();\n\n const hex: string[] = [];\n for (let i = 0; i < 36; i++) {\n if (i === 8 || i === 13 || i === 18 || i === 23) {\n hex.push('-');\n } else if (i === 14) {\n hex.push('4');\n } else if (i === 19) {\n hex.push(((Math.random() * 4) | 8).toString(16));\n } else {\n hex.push(((Math.random() * 16) | 0).toString(16));\n }\n }\n return hex.join('');\n}\n","import type { AttachmentMime } from './api.js';\nimport { InnspelApiError, InnspelConfigError } from './feil.js';\nimport type { AttachmentBody, AttachmentInput } from './typer.js';\n\n/**\n * Grensene for et vedlegg (K9). Tallene er kontraktens\n * (`AttachmentPresignRequest`: 5 MB, 4096²) og sjekkes her FØR noe går på\n * nettet — plattformen sjekker dem på nytt før dekoding.\n */\nexport const VEDLEGG_GRENSER = {\n maxBytes: 5_242_880,\n maxDimension: 4096,\n} as const;\n\n/** Allowlisten (K9): aldri SVG, aldri GIF. Avgjøres på ledningen av magic bytes, ikke av denne strengen. */\nexport const TILLATTE_MIME: readonly AttachmentMime[] = ['image/png', 'image/jpeg', 'image/webp'];\n\n/** Byte-lengden på kroppen, uansett om verten gir Blob, ArrayBuffer eller en typed array. */\nexport function byteLengde(body: AttachmentBody): number {\n if (typeof body === 'object' && body !== null && 'size' in body && typeof body.size === 'number') {\n return body.size;\n }\n return (body as ArrayBuffer | ArrayBufferView).byteLength;\n}\n\n/**\n * Validerer vedlegget slik `init` validerer opsjonene: kaster {@link InnspelConfigError}\n * med feltnavn, før noe treffer nettet. Et vedlegg over grensene er en utviklerfeil\n * i vertens fangst — ikke noe innsenderen skal få 413 for etter å ha ventet.\n */\nexport function validerVedlegg(input: AttachmentInput): void {\n if (input === null || typeof input !== 'object') {\n throw new InnspelConfigError('attachment', 'må være et objekt med { submissionId?, mime, body, width, height }');\n }\n if (!TILLATTE_MIME.includes(input.mime)) {\n throw new InnspelConfigError(\n 'attachment.mime',\n `må være en av ${TILLATTE_MIME.join(', ')}. SVG og GIF er aldri tillatt (K9)`,\n );\n }\n if (input.body === null || input.body === undefined) {\n throw new InnspelConfigError('attachment.body', 'mangler — send bildet som Blob, ArrayBuffer eller Uint8Array');\n }\n const bytes = byteLengde(input.body);\n if (!Number.isFinite(bytes) || bytes < 1) {\n throw new InnspelConfigError('attachment.body', 'er tom');\n }\n if (bytes > VEDLEGG_GRENSER.maxBytes) {\n throw new InnspelConfigError(\n 'attachment.body',\n `er ${bytes} byte, over taket på ${VEDLEGG_GRENSER.maxBytes} (5 MB). Reduser kvaliteten eller oppløsningen ved fangst`,\n );\n }\n for (const felt of ['width', 'height'] as const) {\n const v = input[felt];\n if (!Number.isInteger(v) || v < 1 || v > VEDLEGG_GRENSER.maxDimension) {\n throw new InnspelConfigError(\n `attachment.${felt}`,\n `må være et heltall mellom 1 og ${VEDLEGG_GRENSER.maxDimension} (K9)`,\n );\n }\n }\n}\n\n/** Det presign svarer med, slik `lastOpp` trenger det. */\nexport interface PresignSvar {\n attachmentId: string;\n uploadUrl: string;\n headers: ReadonlyArray<{ name: string; value: string }>;\n}\n\n/**\n * PUT mot den presignede URL-en, med NØYAKTIG headerne presign ga — settet er\n * lukket, og lagringen avviser alt annet (signaturen dekker `Content-Type`).\n *\n * En egen funksjon fordi den ikke går gjennom den genererte klienten: URL-en\n * peker på lagringen, ikke på plattformen, og skal hverken ha tenantKey eller\n * token. En nettverksfeil kastes videre som den er, så kalleren kan skille\n * «nettet er nede» fra «lagringen sa nei».\n */\nexport async function lastOppTilLagring(\n fetchImpl: typeof fetch,\n presign: PresignSvar,\n body: AttachmentBody,\n signal: AbortSignal,\n): Promise<void> {\n const headers: Record<string, string> = {};\n for (const h of presign.headers) headers[h.name] = h.value;\n\n const res = await fetchImpl(new Request(presign.uploadUrl, { method: 'PUT', headers, body, signal }));\n if (!res.ok) {\n throw new InnspelApiError(\n res.status,\n 'unknown',\n `Lagringen avviste opplastingen med status ${res.status}. Bildet ble ikke lagt ved.`,\n );\n }\n}\n","import {\n createClient,\n createConfig,\n ingestAttachmentsComplete,\n ingestAttachmentsPresign,\n ingestConfigGet,\n ingestKnownIssuesConfirm,\n ingestKnownIssuesList,\n ingestProgramsAccept,\n ingestProgramsCompleteTask,\n ingestProgramsDecline,\n ingestProgramsListMine,\n ingestProgramsRespond,\n ingestProgramsWithdraw,\n ingestSubmissionsCreate,\n ingestSubmissionsListMine,\n ingestSubmissionsStatus,\n type ApiErrorBody,\n type AttachmentPresign,\n type AttachmentView,\n type Client,\n type ClientConfig,\n type ErrorCode,\n type FollowUpResponseCreate,\n type KnownIssueCard,\n type MyPrograms,\n type ParticipationView,\n type SubmissionStatusView,\n type TaskCompletionCreate,\n type TaskCompletionView,\n} from './api.js';\nimport { erHeaderTrygg, InnspelApiError, InnspelConfigError, NettverksFeil } from './feil.js';\nimport { hentToken } from './identitet.js';\nimport { flushKo } from './flush.js';\nimport { Ko } from './ko.js';\nimport { slåSammenKontekst, validerKontekst } from './kontekst.js';\nimport { scanText } from './monster.js';\nimport type {\n AttachmentInput,\n AttachmentOutcome,\n CaptureInput,\n CaptureResult,\n ContextInput,\n FlushResult,\n InnspelOptions,\n InnspelStorage,\n KnownIssueQuery,\n MySubmission,\n OpenFeedbackOptions,\n PatternFinding,\n Presenter,\n QueuedSubmission,\n ResolvedSettings,\n Connectivity,\n Telemetry,\n TelemetryEvent,\n} from './typer.js';\nimport { nyClientRef } from './uuid.js';\nimport { byteLengde, lastOppTilLagring, validerVedlegg } from './vedlegg.js';\nimport { VERSJON } from './versjon.js';\n\nconst STANDARD_TIMEOUT_MS = 10_000;\nconst noopTelemetri: Telemetry = { emit: () => undefined };\nconst UTFALL = ['fungerte', 'delvis', 'ikke'] as const;\nconst SETNING_MAKS = 140;\n\n/** Tre lukkede valg og en setning ≤ 140 — samme form for «Gjort» og «Hvordan gikk det?». Utviklerfeil kastes før noe kall går ut. */\nfunction validerUtfall(input: { outcome: string; text?: string | undefined }): void {\n if (!(UTFALL as readonly string[]).includes(input.outcome)) {\n throw new InnspelConfigError('outcome', `må være ett av ${UTFALL.join(' · ')}`);\n }\n if (input.text !== undefined && (typeof input.text !== 'string' || input.text.length > SETNING_MAKS)) {\n throw new InnspelConfigError('text', `er valgfri, men aldri lengre enn ${SETNING_MAKS} tegn`);\n }\n}\n\n/** Klienten `init` gir deg. Én per app; den er trygg å holde på. */\nexport interface InnspelClient {\n /** Versjonen av `@innspel/core`. Følger med hver innsending som `context.sdkVersion`. */\n readonly version: string;\n /** `true` når `identityProvider` er `null` — innsendinger kan ikke følges opp. */\n readonly isAnonymous: boolean;\n /** Vertens nettstatus fra `init({ connectivity })`, eller `null` — da vet widgeten om nettet først når et kall feiler. */\n readonly connectivity: Connectivity | null;\n /** Leietakerens grenser slik klienten kjenner dem. Oppdateres på plass av {@link loadSettings}. */\n readonly settings: ResolvedSettings;\n /** Konteksten som følger hver innsending, med `sdkVersion` satt av kjernen. */\n readonly context: ContextInput & { sdkVersion: string };\n\n /**\n * Henter leietakerens klientkonfigurasjon (`GET /v1/ingest/config`, M2.5): tegngrense,\n * minste antall tegn, skjermbilde og personvernlenke — det verten ellers måtte\n * duplisere i `init()`. Kalles av widgeten ved åpning, aldri ved oppstart (DD-41).\n * Svarer ikke kallet, beholdes det klienten alt har: konfigurasjonen er et tilbud,\n * aldri en sperre. Returnerer `settings` — samme objekt, oppdatert.\n */\n loadSettings(): Promise<ResolvedSettings>;\n\n capture(input: CaptureInput): Promise<CaptureResult>;\n\n readonly knownIssues: {\n /** Kortene som vises FØR feltet i feilsporet (DD-03). Feiler oppslaget, er lista tom. */\n for(query?: KnownIssueQuery): Promise<KnownIssueCard[]>;\n /** «Ja, jeg også» (DD-29): Reach +1 uten ny sak. */\n confirm(knownIssueId: string): Promise<SubmissionStatusView>;\n };\n\n /** Lagringen verten injiserte. Eksponert så widgetene kan lagre det som er per enhet og aldri skal til plattformen (F14). */\n readonly storage: InnspelStorage;\n\n readonly subjects: {\n /** «Mine innspill» (DD-27), med køen gjort synlig (DD-41). */\n submissions(): Promise<MySubmission[]>;\n status(submissionId: string): Promise<SubmissionStatusView>;\n };\n\n readonly programs: {\n /** Alt om betaprogram for innsenderen i ett kall: invitasjoner til banneret (DD-12), deltakelser til fanen, og oppfølginger som venter. */\n list(): Promise<MyPrograms>;\n /**\n * Aksepterer invitasjonen etter forventningsavklaringen (DD-13, DD-32).\n * Tokenet kom fra leietakerens egen kanal — plattformen sender aldri (DD-12).\n * Er det brukt, utløpt eller utstedt til noen andre, kommer 404\n * `invitation_invalid`. Gjentak fra samme innsender er trygt: svaret er den\n * samme deltakelsen.\n */\n accept(invitationToken: string): Promise<ParticipationView>;\n /** Avslår invitasjonen. Ingen årsak spørres. Et nei etter ja er {@link withdraw}, ikke avslag. */\n decline(invitationToken: string): Promise<void>;\n /** «Gå ut» (DD-36): umiddelbart, alltid tilgjengelig, og aldri en straff. Idempotent. */\n withdraw(participationId: string): Promise<ParticipationView>;\n /**\n * «Gjort» (3c): ett av tre lukkede utfall — fungerte · delvis · ikke — og en valgfri\n * setning ≤ 140. Én per oppgave; et gjentak er 409 `task_already_completed`. En egen\n * innsending kan henge ved. Teller `task_completed` med utfallet, aldri teksten.\n */\n completeTask(taskId: string, completion: TaskCompletionCreate): Promise<TaskCompletionView>;\n /**\n * «Hvordan gikk det?» på en utsendt oppfølging fra `list().pendingFollowUps`: de samme\n * tre valgene og en valgfri setning ≤ 140. Bare `hvordan_gikk_det` og `sjekkpunkt` tar\n * svar — en påminnelse eller et tilbud om utgang gir 409 `follow_up_not_answerable`.\n * Engangs (409 `follow_up_already_answered`). Teller `followup_answered`.\n */\n respond(followUpId: string, response: FollowUpResponseCreate): Promise<void>;\n };\n\n readonly attachments: {\n /**\n * Laster opp ett maskert skjermbilde til en innsending som alt er lagret:\n * presign → PUT til lagringen → complete. Bruk `capture({ attachment })` i\n * stedet når teksten og bildet sendes sammen — da håndteres DD-42 for deg.\n * Plattformen verifiserer og re-enkoder etterpå; `processedAt` er satt når\n * det er gjort.\n */\n upload(submissionId: string, attachment: AttachmentInput): Promise<AttachmentView>;\n };\n\n readonly queue: {\n pending(): Promise<QueuedSubmission[]>;\n /** Sendes ellers automatisk når widgeten åpnes. Aldri ved oppstart (DD-41). */\n flush(): Promise<FlushResult>;\n };\n\n /** Mønstervarsel (DD-46). Returnerer funn — fjerner aldri noe. */\n scanText(text: string): PatternFinding[];\n\n /** Emitter en tragt-hendelse. Brukes av UI-laget for `widget_opened` og `track_selected`. */\n track(event: TelemetryEvent): void;\n\n /** Åpner widgeten. Krever `@innspel/react-native`. */\n openFeedback(options?: OpenFeedbackOptions): Promise<void>;\n\n /** Registrerer visningen. Kalles av `@innspel/react-native`, ikke av verten. */\n registerPresenter(presenter: Presenter): void;\n}\n\nfunction krev(betingelse: boolean, felt: string, hva: string): void {\n if (!betingelse) throw new InnspelConfigError(felt, hva);\n}\n\nfunction validerOpsjoner(o: InnspelOptions): void {\n krev(o !== null && typeof o === 'object', 'options', 'mangler — init() tar ett objekt');\n krev(\n typeof o.baseUrl === 'string' && o.baseUrl.length > 0,\n 'baseUrl',\n 'mangler. Sett plattformens API-rot, f.eks. https://api.innspel.example — SDK-et gjetter aldri hvor dataene havner',\n );\n krev(\n typeof o.tenantKey === 'string' && o.tenantKey.length > 0,\n 'tenantKey',\n 'mangler. Den offentlige SDK-nøkkelen finner du i panelet under Innstillinger → Produkter',\n );\n krev(\n erHeaderTrygg(o.tenantKey),\n 'tenantKey',\n 'har tegn som ikke kan stå i en HTTP-header (mellomrom, linjeskift eller tegn utenfor ASCII). Har du kopiert en placeholder med «…» i, bytt den mot den ekte nøkkelen fra panelet',\n );\n krev(\n o.identityProvider === null || typeof o.identityProvider === 'function',\n 'identityProvider',\n 'må være en funksjon som gir et feedback-token, eller null for anonym modus. Anonym modus er et eksplisitt valg, aldri en glemt opsjon',\n );\n\n const s = o.storage as Partial<InnspelOptions['storage']> | undefined;\n krev(s !== null && typeof s === 'object', 'storage', 'mangler. Offline-køen lagres her (DD-41)');\n for (const metode of ['get', 'set', 'remove'] as const) {\n krev(typeof s?.[metode] === 'function', `storage.${metode}`, 'mangler eller er ikke en funksjon');\n }\n\n validerKontekst(o.context ?? {}, 'context', true);\n\n if (o.textMaxLength !== undefined) {\n krev(\n o.textMaxLength === 140 || o.textMaxLength === 280,\n 'textMaxLength',\n 'må være 140 eller 280 — kontrakten har to verdier, og 140 er den som gjelder ved minorsPresent',\n );\n }\n if (o.minTextLength !== undefined) {\n krev(\n Number.isInteger(o.minTextLength) && o.minTextLength >= 1,\n 'minTextLength',\n 'må være et heltall ≥ 1 (DD-44)',\n );\n }\n if (o.telemetry !== undefined) {\n krev(\n typeof o.telemetry?.emit === 'function',\n 'telemetry.emit',\n 'mangler eller er ikke en funksjon',\n );\n }\n if (o.connectivity !== undefined) {\n krev(\n typeof o.connectivity?.isOnline === 'function',\n 'connectivity.isOnline',\n 'mangler eller er ikke en funksjon. Gi et objekt med isOnline() og valgfri subscribe(), eller utelat opsjonen — se docs/sdk/README.md, «Nettstatus»',\n );\n krev(\n o.connectivity.subscribe === undefined || typeof o.connectivity.subscribe === 'function',\n 'connectivity.subscribe',\n 'er valgfri, men må være en funksjon som gir en avmelding tilbake',\n );\n }\n}\n\n/** Oversetter et feilsvar fra plattformen til {@link InnspelApiError}. */\nfunction tilApiFeil(status: number, kropp: unknown, response?: Response): InnspelApiError {\n const body = (kropp ?? {}) as Partial<ApiErrorBody>;\n const kode = (body.code ?? 'unknown') as ErrorCode | 'unknown';\n const retryAfter = Number(response?.headers.get('retry-after') ?? NaN);\n return new InnspelApiError(\n status,\n kode,\n body.message ?? `Kallet feilet med status ${status}.`,\n Number.isFinite(retryAfter) ? retryAfter : undefined,\n );\n}\n\n/**\n * Setter opp SDK-et. Validerer opsjonene ved kjøretid og kaster umiddelbart med\n * feltnavnet ved feil bruk — typer stopper ikke en JavaScript-vert eller en feil\n * `.env` (tech-decisions.md, «SDK — dokumentasjon og utvikleropplevelse»).\n *\n * Kaller ingenting og sender ingenting: køen tømmes ALDRI ved oppstart (DD-41).\n *\n * @example\n * ```ts\n * const innspel = init({\n * baseUrl: 'https://api.innspel.example',\n * tenantKey: 'ik_pub_xxxxxxxx',\n * identityProvider: hentFeedbackToken, // eller null = anonym\n * storage,\n * context: { platform: 'ios', appVersion: '1.4.2' },\n * });\n * ```\n */\nexport function init(options: InnspelOptions): InnspelClient {\n validerOpsjoner(options);\n\n const settings: ResolvedSettings = {\n // Strammest mulig til loadSettings() har svart: 140 / 10 / skjermbilde av er\n // verdiene ved minorsPresent (K18). Verten kan overstyre startverdiene, men\n // det leietakeren har satt i panelet vinner når konfigurasjonen er hentet.\n textMaxLength: options.textMaxLength ?? 140,\n minTextLength: options.minTextLength ?? 10,\n screenshotsEnabled: options.screenshotsEnabled ?? false,\n };\n\n const kontekst = slåSammenKontekst(options.context, undefined, VERSJON);\n const telemetri = options.telemetry ?? noopTelemetri;\n const kø = new Ko(options.storage);\n const anonym = options.identityProvider === null;\n\n /**\n * `fetch` med nettverksfeilene merket. Den genererte klienten fanger det fetch\n * kaster og svarer uten `response`; merket er det eneste som skiller «nettet er\n * nede» fra en feil i vår egen kode. Vertens fetch slås opp ved hvert kall.\n */\n const nett = ((input: Request) =>\n (options.fetch ?? fetch)(input).catch((e: unknown) => {\n throw new NettverksFeil(String(e));\n })) as typeof fetch;\n\n const klient: Client = createClient(createConfig({ baseUrl: options.baseUrl, fetch: nett }));\n\n let presenter: Presenter | null = null;\n\n /** Headere for ett kall. Tokenet hentes friskt hver gang — aldri fra disk (K20). */\n async function headere(): Promise<Record<string, string>> {\n const h: Record<string, string> = { 'X-Innspel-Tenant-Key': options.tenantKey };\n const token = await hentToken(options.identityProvider);\n if (token) h['Authorization'] = `Bearer ${token}`;\n return h;\n }\n\n /**\n * Tidsgrense for ett kall. React Native polyfyller `AbortSignal` uten\n * `AbortSignal.timeout`, og Expo legger den ikke til — der er det en egen\n * `AbortController` med timer, ryddet når kallet er ferdig.\n */\n async function medTidsgrense<T>(kall: (signal: AbortSignal) => Promise<T>): Promise<T> {\n const ms = options.timeoutMs ?? STANDARD_TIMEOUT_MS;\n if (typeof AbortSignal.timeout == 'function') return kall(AbortSignal.timeout(ms));\n const kontroll = new AbortController();\n const timer = setTimeout(() => kontroll.abort(), ms);\n try {\n return await kall(kontroll.signal);\n } finally {\n clearTimeout(timer);\n }\n }\n\n /**\n * Kjører et kall og prøver ÉN gang til ved `feedback_token_expired`.\n *\n * Kontrakten skiller bevisst `expired` fra `invalid`: den første er ventet og\n * håndteres her, den andre er en utviklerfeil i vertens token-endepunkt og\n * skal vises, ikke skjules.\n */\n async function medToken<T>(\n kall: (h: Record<string, string>, s: AbortSignal) => Promise<{ data?: T; error?: unknown; response: Response }>,\n ): Promise<T> {\n // Hvert forsøk får egen tidsgrense. Uten svar er feilen det fetch kastet\n // (NettverksFeil) eller en feil i koden før fetch — begge kastes som de er.\n const forsøk = async () => {\n const h = await headere();\n const r = await medTidsgrense((s) => kall(h, s));\n if (!r.response) throw r.error;\n return r;\n };\n let res = await forsøk();\n if (res.response.status === 401) {\n const feil = tilApiFeil(401, res.error, res.response);\n if (feil.code === 'feedback_token_expired' && !anonym) {\n res = await forsøk();\n }\n }\n if (!res.response.ok) throw tilApiFeil(res.response.status, res.error, res.response);\n return res.data as T;\n }\n\n /** Tokenet kommer fra leietakerens kanal (DD-12); en tom streng er en feil i vertens kobling, ikke et kall. */\n function krevInvitasjonstoken(token: string): void {\n if (typeof token !== 'string' || token.length === 0) {\n throw new InnspelConfigError(\n 'invitationToken',\n 'mangler — det er engangs-tokenet leietakeren sendte i sin egen kanal (dyplenke, varsel eller e-post)',\n );\n }\n }\n\n function krevToken(): void {\n if (anonym) {\n throw new InnspelApiError(\n 401,\n 'feedback_token_required',\n 'Anonym modus har ingen «mine innspill» — det finnes ingen identitet å slå opp.',\n );\n }\n }\n\n async function sendNå(\n input: CaptureInput,\n clientRef: string,\n kontekstForKall: ContextInput & { sdkVersion: string },\n ): Promise<SubmissionStatusView> {\n const body: Record<string, unknown> = {\n type: input.type,\n text: input.text,\n context: kontekstForKall,\n clientRef,\n };\n if (input.programId !== undefined) body['programId'] = input.programId;\n if (input.taskId !== undefined) body['taskId'] = input.taskId;\n if (input.type === 'feil') {\n if (input.correlation !== undefined) body['correlation'] = input.correlation;\n if (input.relatedKnownIssueId !== undefined) {\n body['relatedKnownIssueId'] = input.relatedKnownIssueId;\n }\n }\n\n return medToken<SubmissionStatusView>((h, s) =>\n ingestSubmissionsCreate({\n client: klient,\n headers: h,\n signal: s,\n body: body as never,\n }) as never,\n );\n }\n\n /**\n * Presign → PUT → complete. Bildet går rett til lagringen med nøyaktig\n * headerne presign ga; tenantKey og token følger aldri med dit.\n */\n async function lastOppVedlegg(submissionId: string, vedlegg: AttachmentInput): Promise<AttachmentView> {\n const presign = await medToken<AttachmentPresign>((h, s) =>\n ingestAttachmentsPresign({\n client: klient,\n headers: h,\n signal: s,\n body: {\n submissionId,\n mime: vedlegg.mime,\n bytes: byteLengde(vedlegg.body),\n width: vedlegg.width,\n height: vedlegg.height,\n },\n }) as never,\n );\n\n await medTidsgrense((s) => lastOppTilLagring(nett, presign, vedlegg.body, s));\n\n return medToken<AttachmentView>((h, s) =>\n ingestAttachmentsComplete({\n client: klient,\n headers: h,\n signal: s,\n path: { id: presign.attachmentId },\n }) as never,\n );\n }\n\n /**\n * Tømmer køen med et ferskt token per rad. Delt av og\n * — de to stedene DD-41 sier køen skal tømmes.\n */\n const flushKø = (): Promise<FlushResult> =>\n flushKo(\n kø,\n (rad) => sendNå({ type: rad.type, text: rad.text } as CaptureInput, rad.clientRef, kontekst),\n telemetri,\n );\n\n // Nettet tilbake → køen tømmes. Aldri ved oppstart (DD-41): bare på en hendelse verten melder.\n options.connectivity?.subscribe?.((online) => {\n if (online) void flushKø().catch(() => undefined);\n });\n\n const innspel: InnspelClient = {\n version: VERSJON,\n isAnonymous: anonym,\n connectivity: options.connectivity ?? null,\n settings,\n context: kontekst,\n storage: options.storage,\n\n async loadSettings() {\n try {\n const cfg = await medToken<ClientConfig>((h, s) =>\n ingestConfigGet({ client: klient, headers: h, signal: s }) as never,\n );\n // Bare det som faktisk kom: en fake eller en gammel plattform kan svare\n // med et delvis objekt, og da står det klienten alt har.\n if (cfg?.textMaxLength === 140 || cfg?.textMaxLength === 280) settings.textMaxLength = cfg.textMaxLength;\n if (typeof cfg?.minTextLength === 'number' && cfg.minTextLength >= 1) settings.minTextLength = cfg.minTextLength;\n if (typeof cfg?.screenshotsEnabled === 'boolean') settings.screenshotsEnabled = cfg.screenshotsEnabled;\n if (typeof cfg?.privacyUrl === 'string' && cfg.privacyUrl) settings.privacyUrl = cfg.privacyUrl;\n } catch {\n // Konfigurasjonen er et tilbud (wireframe 2c-prinsippet): svarer den ikke,\n // står de strammeste verdiene, og innsenderen kan fortsatt melde.\n }\n return settings;\n },\n\n async capture(input) {\n const tekst = input.text ?? '';\n if (tekst.length < settings.minTextLength) {\n throw new InnspelConfigError(\n 'text',\n `er ${tekst.length} tegn. Send-knappen skal være inaktiv under minst ${settings.minTextLength} tegn (DD-44)`,\n );\n }\n if (tekst.length > settings.textMaxLength) {\n throw new InnspelConfigError(\n 'text',\n `er ${tekst.length} tegn, over leietakerens grense på ${settings.textMaxLength}`,\n );\n }\n if (input.context) validerKontekst(input.context, 'capture.context', false);\n // Vedlegget valideres FØR teksten sendes: et bilde over grensene er en\n // utviklerfeil i fangsten, og skal feile før noe er lagret.\n if (input.attachment) validerVedlegg(input.attachment);\n\n const clientRef = input.clientRef ?? nyClientRef();\n const kontekstForKall = slåSammenKontekst(options.context, input.context, VERSJON);\n\n let submission;\n try {\n submission = await sendNå(input, clientRef, kontekstForKall);\n } catch (e) {\n if (e instanceof InnspelApiError) {\n telemetri.emit({ name: 'submission_failed', reason: e.code });\n throw e;\n }\n // En feil i koden køes ikke: den ville sett ut som «Ingen nett» med nett\n // på og aldri blitt tømt. Teksten står i vertens felt.\n if (!(e instanceof NettverksFeil)) throw e;\n // Nettverksfeil: teksten mistes aldri. Kun tekst køes — aldri et\n // skjermbilde (rapport 3, kap. 5).\n await kø.leggTil({\n clientRef,\n type: input.type,\n text: tekst,\n queuedAt: new Date().toISOString(),\n });\n telemetri.emit({\n name: 'submission_sent',\n type: input.type,\n hasAttachment: false,\n offlineQueued: true,\n });\n // Et skjermbilde køes aldri (DD-41): det ble forkastet, og UI-et skal si det.\n return input.attachment\n ? { status: 'queued', clientRef, attachment: { status: 'dropped' } }\n : { status: 'queued', clientRef };\n }\n\n // DD-42: teksten er lagret. Bildet lastes opp i egen forespørsel og kan\n // feile alene — innsendingen står uansett, og kvitteringen sier hva som skjedde.\n let attachment: AttachmentOutcome | undefined;\n if (input.attachment) {\n try {\n attachment = { status: 'uploaded', attachment: await lastOppVedlegg(submission.id, input.attachment) };\n } catch (e) {\n attachment = { status: 'failed', error: e instanceof Error ? e : new Error(String(e)) };\n }\n }\n\n telemetri.emit({\n name: 'submission_sent',\n type: input.type,\n hasAttachment: attachment?.status === 'uploaded',\n offlineQueued: false,\n });\n return attachment ? { status: 'sent', submission, attachment } : { status: 'sent', submission };\n },\n\n knownIssues: {\n async for(query = {}) {\n // F28: versjonen hentes fra konteksten som `platform` alt gjør. Uten den gir tjeneren\n // bare kort uten versjonsområde — hvert kort med «Gjelder versjoner» var usynlig i\n // begge widgets, mens panelet tilbød feltet som om det virket (Følget, 2026-09-17).\n const version = query.version ?? kontekst.appVersion;\n try {\n const kort = await medToken<KnownIssueCard[]>((h, s) =>\n ingestKnownIssuesList({\n client: klient,\n headers: h,\n signal: s,\n query: {\n ...(query.screen !== undefined ? { screen: query.screen } : {}),\n ...(version !== undefined ? { version } : {}),\n platform: query.platform ?? kontekst.platform,\n },\n }) as never,\n );\n const liste = kort ?? [];\n telemetri.emit({ name: 'known_issue_shown', count: liste.length });\n return liste;\n } catch {\n // «Treffene er et tilbud, aldri en sperre» (wireframe 2c): svarer ikke\n // sjekken, hoppes den over — rett til feltet, ingen melding.\n return [];\n }\n },\n\n async confirm(knownIssueId) {\n const res = await medToken<SubmissionStatusView>((h, s) =>\n ingestKnownIssuesConfirm({\n client: klient,\n headers: h,\n signal: s,\n path: { id: knownIssueId },\n body: { context: kontekst } as never,\n }) as never,\n );\n telemetri.emit({ name: 'known_issue_confirmed' });\n return res;\n },\n },\n\n subjects: {\n async submissions() {\n krevToken();\n\n const ventende: MySubmission[] = (await kø.les()).map((r) => ({\n pending: true as const,\n clientRef: r.clientRef,\n type: r.type,\n text: r.text,\n queuedAt: r.queuedAt,\n }));\n\n let sendte: SubmissionStatusView[] | undefined;\n try {\n sendte = await medToken<SubmissionStatusView[]>((h, s) =>\n ingestSubmissionsListMine({ client: klient, headers: h, signal: s }) as never,\n );\n } catch (e) {\n // En ekte API-feil skjules aldri — 401 og 429 skal fram.\n if (!(e instanceof NettverksFeil)) throw e;\n // Nettverksfeil er noe annet: køen er LOKAL, og den er hele poenget\n // med «Mine innspill» offline (DD-41). At serveren er utilgjengelig\n // skal ikke skjule raden som venter på nett — det er nøyaktig da\n // innsenderen trenger å se den.\n return ventende;\n }\n\n telemetri.emit({ name: 'status_viewed' });\n return [...ventende, ...(sendte ?? [])];\n },\n\n async status(submissionId) {\n krevToken();\n return medToken<SubmissionStatusView>((h, s) =>\n ingestSubmissionsStatus({\n client: klient,\n headers: h,\n signal: s,\n path: { id: submissionId },\n }) as never,\n );\n },\n },\n\n programs: {\n async list() {\n krevToken();\n return medToken<MyPrograms>((h, s) =>\n ingestProgramsListMine({ client: klient, headers: h, signal: s }) as never,\n );\n },\n\n async accept(invitationToken) {\n krevInvitasjonstoken(invitationToken);\n krevToken();\n const svar = await medToken<ParticipationView>((h, s) =>\n ingestProgramsAccept({\n client: klient,\n headers: h,\n signal: s,\n path: { token: invitationToken },\n }) as never,\n );\n telemetri.emit({ name: 'invitation_accepted' });\n return svar;\n },\n\n async decline(invitationToken) {\n krevInvitasjonstoken(invitationToken);\n krevToken();\n await medToken<void>((h, s) =>\n ingestProgramsDecline({\n client: klient,\n headers: h,\n signal: s,\n path: { token: invitationToken },\n }) as never,\n );\n telemetri.emit({ name: 'invitation_declined' });\n },\n\n async withdraw(participationId) {\n if (typeof participationId !== 'string' || participationId.length === 0) {\n throw new InnspelConfigError('participationId', 'mangler — bruk id fra deltakelsen i programs.list()');\n }\n krevToken();\n return medToken<ParticipationView>((h, s) =>\n ingestProgramsWithdraw({\n client: klient,\n headers: h,\n signal: s,\n path: { id: participationId },\n }) as never,\n );\n },\n\n async completeTask(taskId, completion) {\n if (typeof taskId !== 'string' || taskId.length === 0) {\n throw new InnspelConfigError('taskId', 'mangler — bruk id fra program.tasks i programs.list()');\n }\n validerUtfall(completion);\n krevToken();\n const svar = await medToken<TaskCompletionView>((h, s) =>\n ingestProgramsCompleteTask({\n client: klient,\n headers: h,\n signal: s,\n path: { id: taskId },\n body: completion,\n }) as never,\n );\n telemetri.emit({ name: 'task_completed', outcome: completion.outcome });\n return svar;\n },\n\n async respond(followUpId, response) {\n if (typeof followUpId !== 'string' || followUpId.length === 0) {\n throw new InnspelConfigError('followUpId', 'mangler — bruk id fra pendingFollowUps i programs.list()');\n }\n validerUtfall(response);\n krevToken();\n await medToken<void>((h, s) =>\n ingestProgramsRespond({\n client: klient,\n headers: h,\n signal: s,\n path: { id: followUpId },\n body: response,\n }) as never,\n );\n telemetri.emit({ name: 'followup_answered' });\n },\n },\n\n attachments: {\n async upload(submissionId, attachment) {\n if (typeof submissionId !== 'string' || submissionId.length === 0) {\n throw new InnspelConfigError('submissionId', 'mangler — bruk id fra innsendingen capture() ga');\n }\n validerVedlegg(attachment);\n return lastOppVedlegg(submissionId, attachment);\n },\n },\n\n queue: {\n pending: () => kø.les(),\n flush: flushKø,\n },\n\n scanText,\n\n track: (event) => telemetri.emit(event),\n\n async openFeedback(åpneOpsjoner) {\n if (!presenter) {\n throw new InnspelConfigError(\n 'openFeedback',\n 'krever en visning. @innspel/core har ingen UI — installer @innspel/react-native og pakk appen i <InnspelProvider>. Trenger du å sende uten widget, bruk capture()',\n );\n }\n // Køen tømmes når widgeten åpnes — aldri ved oppstart (DD-41).\n await flushKø();\n await presenter.open(åpneOpsjoner);\n },\n\n registerPresenter(p) {\n presenter = p;\n },\n };\n\n return innspel;\n}\n","/**\n * Geometrien bak maskeringen (DD-39, DD-40) — ren TypeScript uten UI, så den\n * kan testes her og brukes likt av `@innspel/react-native` og `@innspel/web`.\n *\n * Alt er rektangler i BILDETS pikselkoordinater. UI-laget tegner dem som\n * heldekkende flater over forhåndsvisningen og rekomponerer bitmapen; det som\n * står her avgjør bare HVOR flatene ligger. Private views (DD-39) er rektangler\n * som UI-et aldri lar brukeren fjerne — den regelen håndheves der, ikke her,\n * fordi den handler om hvem som la rektangelet, ikke om geometri.\n */\n\nexport interface MaskPoint {\n x: number;\n y: number;\n}\n\nexport interface MaskRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Ett fingerstrøk («Tegn over», DD-40) til rektangler: en kvadratisk flate per\n * punkt, og én per mellomrom mellom to punkter, så strøket er tett selv om\n * fingeren beveget seg fort. Alle klippes til bildet.\n */\nexport function strokTilRekter(punkter: readonly MaskPoint[], penselBredde: number, bilde: { width: number; height: number }): MaskRect[] {\n if (penselBredde <= 0 || punkter.length === 0) return [];\n const halv = penselBredde / 2;\n const ut: MaskRect[] = [];\n\n const legg = (p: MaskPoint) => {\n const r = klipp({ x: p.x - halv, y: p.y - halv, width: penselBredde, height: penselBredde }, bilde);\n if (r) ut.push(r);\n };\n\n legg(punkter[0]!);\n for (let i = 1; i < punkter.length; i++) {\n const a = punkter[i - 1]!;\n const b = punkter[i]!;\n const avstand = Math.hypot(b.x - a.x, b.y - a.y);\n // Fyll gapet med mellomliggende kvadrater når fingeren beveget seg mer enn\n // en halv penselbredde — ellers blir strøket en rekke løse prikker.\n const steg = Math.max(1, Math.ceil(avstand / halv));\n for (let s = 1; s <= steg; s++) {\n legg({ x: a.x + ((b.x - a.x) * s) / steg, y: a.y + ((b.y - a.y) * s) / steg });\n }\n }\n return ut;\n}\n\n/** «Masker felt» (DD-40): ett trykk legger en boks sentrert på punktet. */\nexport function trykkTilRekt(punkt: MaskPoint, boks: { width: number; height: number }, bilde: { width: number; height: number }): MaskRect | null {\n return klipp({ x: punkt.x - boks.width / 2, y: punkt.y - boks.height / 2, width: boks.width, height: boks.height }, bilde);\n}\n\n/**\n * Klipper et rektangel til bildet. Null når ingenting er igjen — et rektangel\n * helt utenfor bildet skal ikke tegnes, og heller ikke telles som en maskering.\n */\nexport function klipp(r: MaskRect, bilde: { width: number; height: number }): MaskRect | null {\n const x1 = Math.max(0, r.x);\n const y1 = Math.max(0, r.y);\n const x2 = Math.min(bilde.width, r.x + r.width);\n const y2 = Math.min(bilde.height, r.y + r.height);\n if (x2 <= x1 || y2 <= y1) return null;\n return { x: x1, y: y1, width: x2 - x1, height: y2 - y1 };\n}\n\n/**\n * Skalerer et rektangel fra ett koordinatsystem til et annet — typisk fra\n * skjermpunkter (der fingeren var) til bildepiksler (der masken skal ligge).\n * Rundes UTOVER: en maske skal aldri bli en piksel for liten.\n */\nexport function skaler(r: MaskRect, fra: { width: number; height: number }, til: { width: number; height: number }): MaskRect {\n const sx = til.width / fra.width;\n const sy = til.height / fra.height;\n const x = Math.floor(r.x * sx);\n const y = Math.floor(r.y * sy);\n return {\n x,\n y,\n width: Math.ceil((r.x + r.width) * sx) - x,\n height: Math.ceil((r.y + r.height) * sy) - y,\n };\n}\n\n/** Om et punkt ligger i et av rektanglene — brukes for «trykk på en maske for å angre den». */\nexport function treffer(punkt: MaskPoint, r: MaskRect): boolean {\n return punkt.x >= r.x && punkt.x < r.x + r.width && punkt.y >= r.y && punkt.y < r.y + r.height;\n}\n\n/**\n * Om rektanglene dekker hele bildet. UI-et bruker det til å si «alt er\n * maskert» — da er det ingenting å sende, og «Fjern bildet» er det ærlige valget.\n */\nexport function dekkerAlt(rekter: readonly MaskRect[], bilde: { width: number; height: number }): boolean {\n return rekter.some((r) => r.x <= 0 && r.y <= 0 && r.x + r.width >= bilde.width && r.y + r.height >= bilde.height);\n}\n"]}
|