npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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/core

Quickstart

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-native

Alt 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). clientRef er en ny UUID per innsending og identifiserer aldri enheten
  • Ingen nettleser-API-er: localStorage, document, window og navigator finnes 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.