Aplicatie desktop pentru atelierul de electronica. Face doua lucruri:
- Cauta si arhiveaza documentatie -- datasheet-uri, scheme, note de aplicatie si manuale de service -- le descarca si le tine local, organizate si cautabile.
- Tine evidenta componentelor din sertare: ce ai, cat mai ai si unde e. Iar ce nu ai, il cauta la furnizori.
Accentul e pe ce e greu sau imposibil de gasit: integrate scoase din productie, clone est-europene, cipuri din anii '70-'90 care nu mai au pagina la niciun producator.
npm install
npm run devLa prima pornire aplicatia intreaba unde sa tina librăria. Fisierele raman
PDF-uri obisnuite pe disc, organizate ca
<librarie>/<tip>/<producator>/<PART_NUMBER>/, deci sunt utilizabile si direct
din Explorer, fara aplicatie.
npm run distProduce release/PartsVault-0.1.0-portabil.exe — un singur fisier, fara
instalare. La prima pornire isi creeaza langa el folderul PartsVault-Date/, in
care tine tot: config.json, indexul si documentele descarcate. Nu scrie nimic
in alta parte din sistem, deci poate fi mutat pe stick sau pe alt calculator cu
tot cu librarie.
In varianta portabila nu mai apare ecranul care intreaba unde sa salveze — raspunsul e intotdeauna "langa executabil". Calea ramane schimbabila din Setari.
La pornire verifica GitHub Releases si, daca a aparut o versiune noua, ofera descarcarea printr-un banner. Executabilul nou se pune langa cel curent, porneste, iar cel vechi e sters.
Doua detalii care nu sunt evidente si care strica implementarea daca lipsesc:
process.execPathnu ajuta. Exe-ul portabil se auto-extrage in%TEMP%\<random>\la fiecare pornire, deciexecPatharata spre copia temporara. Folderul real, unde sta fisierul pe care il deschide omul, vine dinPORTABLE_EXECUTABLE_DIR, setata de wrapper-ul electron-builder.- Stergerea vechiului exe are nevoie de reincercari.
app.quit()doar programeaza inchiderea, deci procesul inlocuit poate tine inca lock pe fisierul lui in momentul in care pornim. O singura incercare esueaza tacut si lasa gunoiul acolo pana la urmatoarea repornire; curatarea ruleaza de trei ori, imediat, la 5 si la 20 de secunde.
Consecinta: nu tine mai multe versiuni in acelasi folder — curatarea sterge
orice PartsVault-<versiune>-portabil.exe mai vechi decat cel care ruleaza.
Valoarea aplicatiei nu sta in a interoga Google, ci in ce face inainte si dupa cautare.
Un datasheet e indexat pe web sub radacina piesei, nu sub codul complet de
comanda. analyzePart() (src/main/partnumber.ts) sparge inputul in variante
ordonate dupa specificitate:
| Ai tastat | Aplicatia cauta |
|---|---|
LM358ADGKR |
LM358ADGK, LM358AD, ... LM358 |
STM32F103C8T6 |
STM32F103C8T6, STM32F103C8, STM32F103 |
C945 |
2SC945 (marcajul de pe capsula omite prefixul JIS) |
Apoi intra tabelul de echivalente (src/main/equivalents.ts), care e
adevarata solutie pentru piesele imposibile. Nimeni nu publica fisa tehnica a
lui CDB400E, dar e acelasi cip cu SN7400:
| Piesa | Echivalent gasit | De ce |
|---|---|---|
CDB400E |
SN7400, 7400 | CDB4xx = seria TTL 74xx de la Microelectronica Bucuresti |
MMC4011 |
CD4011, HEF4011B | MMC = seria CMOS 4000 fabricata in Romania |
K155LA3 |
SN7400 | seria sovietica 155 = TTL 74xx; codul de functie ЛА3 = poarta SI-NU cuadrupla |
К561ЛА7 |
CD4011 | acelasi tabel, seria CMOS; se accepta si input cirilic |
MAA741 |
UA741, LM741 | Tesla MAA741 = amplificatorul operational clasic |
Codurile sovietice nu se traduc aritmetic — ЛА3 inseamna "SI-NU, tipul 3",
nu "numarul 3" — asa ca sunt rezolvate printr-un tabel de coduri de functie, nu
prin regula. Tabelul contine doar corespondentele bine documentate: o intrare
gresita e mai daunatoare decat una lipsa, fiindca trimite cautarea pe o piesa
fara legatura in loc sa cada elegant pe cautarea generica.
Agregatoarele returneaza frecvent pagini de eroare sau HTML de captcha cu
Content-Type mincinos. verifyDocument() (src/main/verify.ts) deschide
fiecare PDF descarcat, extrage textul si confirma ca part number-ul chiar apare
in el. Nimic nu ajunge pe disc inainte de verificare.
Textul fiselor sovietice e scris cu chirilice (in PDF scrie К155ЛА3), deci
verificarea transliterează inainte de comparatie — altfel n-ar confirma
niciodata piesa cautata.
Fiecare document primeste un nivel de incredere:
- verificat — part number-ul apare in document
- probabil — documentul acopera familia sau echivalentul piesei
- nesigur — PDF scanat, fara strat de text
Nucleul e fix -- part number, categorie, tip, cantitate si locatie fizica (depozitare, rand, coloana) -- fiindca pe el se sprijina cautarea, sortarea si alertele de stoc. Restul il definesti tu: campuri de caracteristici de tip text, numar, lista de optiuni sau da/nu, cu unitate de masura, optional restranse la anumite categorii, ca formularul unui rezistor sa nu ceara frecventa de ceas.
Campurile propuse la prima pornire (valoare, toleranta, tensiune, putere, capsula, montaj) sunt o sugestie, nu o structura impusa: pot fi sterse toate.
Cautarea merge si dupa locatie, deci poti intreba "ce am in cutia A". Pe fiecare componenta poti pune un prag sub care e semnalata ca fiind pe terminate.
Rezultatele apar intr-un singur tabel, cu denumirea gasita la furnizor, daca e sau nu in stoc, si pretul.
| Furnizor | Regiune | Integrare | Ce cere | Cost |
|---|---|---|---|---|
| Mouser ✔ | International | API | API key | gratuit |
| Farnell | Romania | API | API key | gratuit |
| TME | Romania | API | Token + secret (HMAC) | gratuit |
| DigiKey | International | API | Client ID + secret (OAuth) | gratuit |
| RS Components | Romania | cautare in browser | — | — |
| Optimus Digital | Romania | cautare in browser | — | — |
| Cleste | Romania | cautare in browser | — | — |
| Nexar / Octopart | agregator | API | Client ID + secret | abonament |
Fara nicio configurare, fiecare furnizor apare in tabel ca link catre cautarea lui, cu codul completat -- merge intotdeauna si nu se strica. Cu o cheie pusa in Setari, furnizorul intoarce denumire, stoc, pret si datasheet direct in aplicatie. Cheile stau local, in fisierul de configurare, si nu pleaca nicaieri.
Primele patru dau cheie gratuita. Nu-ti trebuie toate -- fiecare in parte umple tabelul cu randul lui. Incepe cu Mouser, e cel mai rapid de obtinut.
✔ = integrare testata pe o cheie reala. Cu Mouser, LM358 intoarce stoc si
pret in lei, de pe storefront-ul romanesc. Celelalte sunt scrise dupa
documentatie, dar inca neverificate pe date adevarate.
Nexar / Octopart ar fi fost varianta ideala -- un singur apel acopera toti
distribuitorii -- dar datele de stoc cer abonament platit. Testat pe cont real:
autentificarea si interogarea trec, iar raspunsul e
You have exceeded your part limit of 0. Integrarea ramane in aplicatie pentru
cine are oricum abonament, dar pentru cateva piese pe luna n-are sens sa
platesti agregarea cand fiecare distribuitor da acces gratuit la ale lui.
De ce e nevoie de chei: citirea automata a paginilor de magazin nu e o alternativa. Verificat pe viu, cu randare intr-un browser complet: Mouser, DigiKey, TME si Farnell raspund toate cu verificare anti-bot (Cloudflare Turnstile). Aplicatia nu incearca sa o ocoleasca. Magazinele mici romanesti randeaza normal, dar de obicei n-au in catalog piesele cautate aici.
Sursele sunt interogate pe niveluri, de la ieftin si sigur catre scump si incert. Daca un nivel superior da rezultate bune si nu ai bifat cautare profunda, cautarea se opreste acolo.
| Nivel | Sursa | Note |
|---|---|---|
| local | Libraria ta | verificata prima, ca sa nu descarci de doua ori |
| producator | Tipare directe de URL | TI, ST, onsemi, ADI, Nexperia, Diodes, Espressif |
| web | Bing (RSS) + DuckDuckGo | filetype:pdf, cu rotatie intre motoare |
| agregator | Datasheet4U, The Datasheet Archive | pentru piese obsolete |
| arhiva | Internet Archive, Bitsavers, World Radio History, Elektrotanya | databook-uri si manuale scanate |
Tiparele directe sunt cea mai valoroasa categorie: nu au rate limiting, deci fiecare tipar functional valoreaza cat zece interogari de motor de cautare.
Motoarele interogate cu fetch() nu suporta rafale, iar felul in care cedeaza e
o capcana. Masurat pe viu:
- DuckDuckGo intoarce o pagina de anomaly dupa cateva interogari;
- Bing e mai perfid — continua sa raspunda
200cu zece rezultate, dar complet nerelevante (linii aeriene, forumuri de mail) in loc sa semnaleze eroarea.
De aceea aplicatia valideaza relevanta raspunsurilor: cand interogarea are un token distinctiv (numar de model, cod de piesa), macar un rezultat trebuie sa-l contina. Verificarea pe orice cuvant nu ajunge — pentru "Logitech Z5500", zece link-uri catre logitech.com contin "logitech" si ar parea valide.
Solutia de fond a fost sa nu mai folosim fetch(). Electron are un Chromium
complet inauntru: aceleasi pagini incarcate intr-o fereastra ascunsa executa
JavaScript, au cookie-uri si arata exact ca la un utilizator real. Diferenta nu
e cosmetica — pentru Logitech Z5500 service manual, fetch intorcea zero
rezultate, iar randarea a adus 37, printre care Elektrotanya si ManualsLib.
Randarea e in src/main/browser.ts, cu sesiune persistenta (cookie-urile de
consimtamant se aduna in timp) si imagini blocate, ca sa fie rapida. Motoarele
pe fetch raman ca rezerva: cand functioneaza, sunt mult mai ieftine.
Sursele de datasheet-uri se strica in timp: domenii care expira, Cloudflare care se strange, tipare de URL care se schimba. Cand cautarea incepe sa dea gres, asta e primul lucru de rulat — arata exact ce a cazut, ca sa nu cauti bug-ul in cod cand de fapt a murit un site:
npm run probe:sourcesPentru o cautare cap-coada pe o piesa anume, in afara interfetei:
node scripts/run.mjs probe CDB400ESurse verificate si scoase intentionat: AllDatasheet si AllTransistors
dau 403 (Cloudflare), DatasheetsPDF si DatasheetCatalog nu mai rezolva
DNS-ul. Nu au adaptoare, ca sa nu piardem timp pe surse care esueaza garantat.
src/
main/ procesul Electron: motorul si datele
partnumber.ts normalizare, variante, producator din prefix
equivalents.ts tabele de echivalente RO / URSS / Tesla / RFT
verify.ts validare PDF, extragere text, clasificare, incredere
download.ts descarcare cu limita de marime si deduplicare pe hash
import.ts import manual, pentru sursele fara descarcare automata
browser.ts randare de pagini intr-un Chromium ascuns
library.ts index JSON + organizare pe disc
inventory.ts componente, schema definita de utilizator, export CSV
suppliers.ts link-out la magazine + API Mouser si Farnell
http.ts User-Agent de browser, throttling per host, retry
search/
orchestrator.ts cascada pe niveluri, scoring, oprire timpurie
sources/ cate un adaptor per sursa
preload/ puntea IPC, singura suprafata expusa interfetei
renderer/ interfata React
scripts/ harness de diagnostic, ruleaza in afara Electron
Diagnostic pentru inventar si furnizori, fara sa deschizi interfata:
node scripts/run.mjs probe-inventoryOrice atinge randarea de pagini are nevoie de un Chromium adevarat, deci ruleaza prin Electron, nu prin harness-ul obisnuit:
node scripts/run-electron.mjs probe-app "Logitech Z5500"Libraria foloseste un index JSON, nu SQLite, ca sa nu existe dependinte native — aplicatia trebuie sa se instaleze fara build tools. La zeci de mii de documente ar merita schimbat.
Datasheet-urile si notele de aplicatie sunt distribuite liber de producatori. Manualele de service (Elektrotanya) sunt de regula sub drept de autor — sursa e inclusa pentru uz personal offline si poate fi dezactivata din Setari, ca oricare alta.
Aplicatia respecta o pauza intre cereri catre acelasi domeniu (implicit 900 ms). Sub 500 ms risti sa fii blocat temporar de agregatoare.