@innspel/core
v0.6.0
Published
Kjernen i Innspels SDK: innsending, kjente feil, offline-kø og mønstervarsel. Ren TypeScript uten runtime-avhengigheter.
Readme
@innspel/core
Kjernen i Innspels SDK. Ren TypeScript: ingen nettleser-API-er, ingen runtime-avhengigheter (K19), ingen stabil identifikator på enheten (K20). Lagring og identitet injiseres av verten.
Bygger du en React Native-app, installer @innspel/react-native
i stedet — den gir deg widgeten og en lagringsadapter, og bruker denne pakken under.
npm install @innspel/coreQuickstart
import { init } from '@innspel/core';
const innspel = init({
baseUrl: 'https://api.innspel.example', // din plattform-URL
tenantKey: 'ik_pub_xxxxxxxx', // offentlig SDK-nøkkel fra panelet
identityProvider: hentFeedbackToken, // eller null = anonym modus
storage, // se «Lagring» under
context: { platform: 'ios', appVersion: '1.4.2' },
});
await innspel.capture({ type: 'feil', text: 'Dørlista er tom etter kl. 22.' });Det er hele veien til første innsending. Alt annet under er valgfritt.
Leietakerens grenser — tegngrense, minste antall tegn, om skjermbilde finnes og
personvernlenken — hentes fra plattformen med innspel.loadSettings(). Widgetene
gjør det ved åpning, aldri ved oppstart. Til kallet har svart gjelder de strammeste
verdiene (140 tegn, 10 som minimum, skjermbilde av); textMaxLength,
minTextLength og screenshotsEnabled i init() er bare startverdier, og det
leietakeren har satt i panelet vinner. Svarer ikke kallet, kan innsenderen
fortsatt melde.
De fire opsjonene du må gi
| Opsjon | Hva |
|---|---|
| baseUrl | Plattformens API-rot. Ingen standard — SDK-et skal aldri gjette hvor dataene dine havner. |
| tenantKey | Den offentlige SDK-nøkkelen. Skrivende, bundet til bundle-ID eller origin, kan aldri lese andres data (K3). Den hører hjemme i appens konfig, ikke i en hemmelighet. |
| identityProvider | Funksjon som gir et ferskt feedback-token, eller null for anonym modus. Se under. |
| storage | Tre metoder. Offline-køen bor her. |
context.platform er påkrevd; appVersion, build, os, screen og locale er
valgfrie. Feltlista er en lukket hviteliste (K5) — et ukjent felt avvises av
plattformen med unknown_field, og SDK-et sender aldri enhets-ID eller IP.
Identitet
Plattformen eier aldri sluttbrukerne dine. Du utsteder et kortlevd token, den verifiserer det og lærer aldri hvem det peker på:
const hentFeedbackToken = async () => {
const res = await fetch('https://din-app.example/api/innspel-token', {
headers: { Authorization: `Bearer ${dinEgenSesjon}` },
});
return (await res.json()).token; // ES256-JWT, aud=innspel, exp ≤ 15 min
};Token-endepunktet er det eneste du må bygge selv. Integrasjonsguiden viser det med kjørbar kode.
identityProvider: null er anonym modus: innsendinger sendes uten avsender,
teller aldri i distinkt Reach og kan ikke følges opp. Det er et eksplisitt valg —
en glemt opsjon gir en feilmelding, aldri stille anonymitet.
Kaster funksjonen din, eller returnerer den null, faller SDK-et tilbake til
anonym modus for det kallet og logger [innspel] til konsollen. Innsenderen skal
kunne melde fra selv om innloggingen din er nede.
Lagring
interface InnspelStorage {
get(key: string): Promise<string | null>;
set(key: string, value: string): Promise<void>;
remove(key: string): Promise<void>;
}Bruk hva du vil — MMKV, AsyncStorage, SQLite, et objekt i minnet.
@innspel/react-native gir deg en ferdig.
API
innspel.capture({ type, text, attachment?, context?, correlation?, relatedKnownIssueId?, clientRef? })
innspel.knownIssues.for({ screen?, version?, platform? }) // kortene som vises FØR feltet
innspel.knownIssues.confirm(id) // «Ja, jeg også» — Reach +1, ingen ny sak
innspel.subjects.submissions() // «Mine innspill», inkl. det som venter på nett
innspel.subjects.status(submissionId) // status for én egen innsending
innspel.programs.list() // invitasjoner, deltakelser, oppfølginger
innspel.programs.accept(invitationToken) // ja til invitasjonen — tokenet kom i DIN kanal
innspel.programs.decline(invitationToken) // nei. Ingen årsak spørres
innspel.programs.withdraw(participationId) // «Gå ut» — umiddelbart, alltid tillatt
innspel.attachments.upload(submissionId, attachment) // skjermbilde til en innsending som alt er lagret
innspel.queue.pending() // det som ligger i offline-køen
innspel.queue.flush() // sendes ellers automatisk
innspel.scanText(text) // mønstervarsel, se under
innspel.openFeedback() // krever @innspel/react-nativeAlt er dokumentert med TSDoc i editoren din. Typene er generert fra API-kontrakten, så feltdokumentasjonen er den samme som plattformen håndhever.
Offline-køen
Faller nettet, køes innsendingen lokalt — kun teksten, aldri et skjermbilde. Taket er 30; innsending nummer 31 avvises med en synlig melding i stedet for å kaste den eldste (DD-41). Køen tømmes når widgeten åpnes eller nettet kommer tilbake, aldri ved oppstart, og hver flush henter et ferskt token — det gamle er utløpt for lengst.
Vis køen for brukeren. queue.pending() gir deg radene, og «Venter på nett —
sendes automatisk» er teksten widgeten bruker.
Vedlegg
Ett skjermbilde per innsending, maskert på klienten før det forlater enheten
(K4). Kjernen har ingen fangst og ingen maskering selv — @innspel/react-native
har begge; her tar du imot bildet som Blob, ArrayBuffer eller Uint8Array:
const res = await innspel.capture({
type: 'feil',
text: 'Dørlista er tom etter kl. 22.',
attachment: { mime: 'image/jpeg', body: blob, width: 1170, height: 2532 },
});
if (res.status === 'sent' && res.attachment?.status === 'failed') {
// Teksten ER lagret. Si «Sendt — skjermbildet kunne ikke legges ved» (DD-42).
}Teksten sendes først, bildet etterpå i egen forespørsel direkte til lagringen, og
bildet kan feile alene — innsendingen står uansett. Uten nett køes teksten og
bildet forkastes (attachment.status === 'dropped'); et skjermbilde køes aldri.
Grensene sjekkes før noe går på nettet og kaster med feltnavn: PNG, JPEG eller WebP (aldri SVG eller GIF), høyst 5 MB og 4096 × 4096 (K9). Plattformen sjekker dem igjen, re-enkoder bildet i en isolert prosess og fjerner EXIF.
Geometrien bak maskeringen — fingerstrøk og trykk til rektangler i bildets
piksler — ligger her (strokTilRekter, trykkTilRekt, skaler, klipp), så
@innspel/react-native og @innspel/web maskerer likt.
Mønstervarsel
innspel.scanText('Kontoen min er [email protected]');
// [{ kind: 'email', match: '[email protected]', start: 15, end: 32 }]Finner e-post, telefonnummer, kortnummer (Luhn-validert), IP-adresser og token-lignende strenger. Den fjerner aldri noe (DD-46) — du viser funnet, brukeren velger «Fjern» eller «Behold». Innsenderen skal alltid se hva som sendes.
Telemetri
import { createIngestTelemetry } from '@innspel/core/telemetri';
init({
…,
telemetry: createIngestTelemetry({ baseUrl, tenantKey, platform: 'ios', appVersion: '1.4.2' }),
});createIngestTelemetry sender hendelsene til plattformens eget mottak (M4.2) —
aldri til en tredjepart. Kallet er anonymt: ingen token, aldri pseudonym, aldri
tekst; bunten bærer bare plattform, appversjon og SDK-versjon. Hendelsene samles i
inntil 2 s og sendes én gang uten nye forsøk; flush() sender det som venter, for
når appen går i bakgrunnen. Understien holder hovedbundelen urørt.
Standard er noop: utelater du opsjonen, sendes ingenting noe sted. Vil du heller
ha hendelsene i egen analyse, gi et objekt med emit(e). Hendelsene bærer aldri
tekst, skjermbilde eller pseudonym.
Feil
Alt fra plattformen kommer som InnspelApiError med en code du kan forgrene på —
aldri på meldingsteksten:
try {
await innspel.capture({ type: 'feil', text });
} catch (e) {
if (e instanceof InnspelApiError && e.code === 'text_too_short') { … }
}feedback_token_expired håndteres internt: SDK-et ber identityProvider om et
nytt token og prøver på nytt, én gang. Den ser du aldri.
Versjoner
Semver fra 0.1.0. Før 1.0.0 kan en minor bryte — pin en eksakt versjon om
du trenger ro. Endringer i API-kontrakten er alltid minst minor, fordi de er en
SDK-endring hos deg.
Grenser SDK-et holder
- Ingen tredjeparts-SDK: ingen analytics, ingen crash-rapportering, ingen annonser (K19)
- Ingen install-ID, ingen device-ID, ingen fingeravtrykk (K20).
clientRefer en ny UUID per innsending og identifiserer aldri enheten - Ingen nettleser-API-er:
localStorage,document,windowognavigatorfinnes ikke i denne pakken - Under 10 kB gzip
Lisens
MIT. Klientpakkene er permissivt lisensiert fordi koden kjører hos deg og må kunne leses og granskes der. Plattformen bak — API, panel og drift — er det ikke.
