@offscript/sdk 0.0.0-stage → 0.1.0

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.
Files changed (70) hide show
  1. package/README.md +133 -2
  2. package/dist/adapters/nuxt.cjs +16 -0
  3. package/dist/adapters/nuxt.cjs.map +1 -0
  4. package/dist/adapters/nuxt.d.ts +10 -0
  5. package/dist/adapters/nuxt.js +14 -0
  6. package/dist/adapters/nuxt.js.map +1 -0
  7. package/dist/adapters/vanilla.cjs +18 -0
  8. package/dist/adapters/vanilla.cjs.map +1 -0
  9. package/dist/adapters/vanilla.d.ts +6 -0
  10. package/dist/adapters/vanilla.js +5 -0
  11. package/dist/adapters/vanilla.js.map +1 -0
  12. package/dist/adapters/vue.cjs +24 -0
  13. package/dist/adapters/vue.cjs.map +1 -0
  14. package/dist/adapters/vue.d.ts +18 -0
  15. package/dist/adapters/vue.js +21 -0
  16. package/dist/adapters/vue.js.map +1 -0
  17. package/dist/chunk-3NX2AGXM.cjs +2671 -0
  18. package/dist/chunk-3NX2AGXM.cjs.map +1 -0
  19. package/dist/chunk-3OSCH7J2.js +2658 -0
  20. package/dist/chunk-3OSCH7J2.js.map +1 -0
  21. package/dist/chunk-B6GO5FE5.cjs +442 -0
  22. package/dist/chunk-B6GO5FE5.cjs.map +1 -0
  23. package/dist/chunk-HAPNSHFG.cjs +20 -0
  24. package/dist/chunk-HAPNSHFG.cjs.map +1 -0
  25. package/dist/chunk-LFXHB4PN.js +426 -0
  26. package/dist/chunk-LFXHB4PN.js.map +1 -0
  27. package/dist/chunk-MBYNQSKA.js +17 -0
  28. package/dist/chunk-MBYNQSKA.js.map +1 -0
  29. package/dist/core/ApiClient.d.ts +24 -0
  30. package/dist/core/LifecycleManager.d.ts +26 -0
  31. package/dist/core/OffscriptSDK.d.ts +98 -0
  32. package/dist/core/SessionManager.d.ts +44 -0
  33. package/dist/core/config.d.ts +2 -0
  34. package/dist/index.cjs +98 -0
  35. package/dist/index.cjs.map +1 -0
  36. package/dist/index.d.ts +13 -0
  37. package/dist/index.js +5 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/playwright/ActionNormalizer.d.ts +37 -0
  40. package/dist/playwright/PlaywrightDataContract.d.ts +88 -0
  41. package/dist/playwright/SelectorGenerator.d.ts +26 -0
  42. package/dist/playwright/index.d.ts +3 -0
  43. package/dist/playwright.cjs +56 -0
  44. package/dist/playwright.cjs.map +1 -0
  45. package/dist/playwright.js +3 -0
  46. package/dist/playwright.js.map +1 -0
  47. package/dist/privacy/DataSanitizer.d.ts +32 -0
  48. package/dist/privacy/PrivacyConfig.d.ts +4 -0
  49. package/dist/recorders/ActionRecorder.d.ts +46 -0
  50. package/dist/recorders/ContextRecorder.d.ts +23 -0
  51. package/dist/recorders/ErrorRecorder.d.ts +20 -0
  52. package/dist/recorders/HTTPRecorder.d.ts +28 -0
  53. package/dist/recorders/IframeRecorder.d.ts +19 -0
  54. package/dist/recorders/RRWebRecorder.d.ts +29 -0
  55. package/dist/recorders/types.d.ts +25 -0
  56. package/dist/transport/EventQueue.d.ts +28 -0
  57. package/dist/transport/EventTransport.d.ts +84 -0
  58. package/dist/transport/PersistentBuffer.d.ts +60 -0
  59. package/dist/transport/RetryManager.d.ts +9 -0
  60. package/dist/types/config.d.ts +115 -0
  61. package/dist/types/events.d.ts +185 -0
  62. package/dist/types/session.d.ts +77 -0
  63. package/dist/utils/errors.d.ts +41 -0
  64. package/dist/utils/id.d.ts +1 -0
  65. package/dist/utils/misc.d.ts +20 -0
  66. package/docs/api-contract.md +56 -0
  67. package/docs/architecture.md +38 -0
  68. package/docs/event-contract.md +26 -0
  69. package/docs/playwright-contract.md +39 -0
  70. package/package.json +78 -3
package/README.md CHANGED
@@ -1,3 +1,134 @@
1
- # Temporary Holding Version
1
+ # @offscript/sdk
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ SDK de instrumentação para aplicações web testadas manualmente por QA. Captura, de forma modular e agnóstica de framework, tudo o que é necessário para **reproduzir** a sessão (rrweb), **investigar** (ações, rede, erros, contexto) e, no futuro, **automatizar** (contrato Playwright), enviando os eventos para a API da Offscript.
4
+
5
+ Funciona em JS puro, Vue 2/3, Nuxt, React, Laravel Blade e Inertia, em SPA e MPA. O núcleo não depende de nenhum framework.
6
+
7
+ > Estado: `0.1.0`. Veja [Limitações conhecidas](#limitações-conhecidas) e o [relatório de testes](#testes).
8
+
9
+ ## Instalação
10
+
11
+ ```bash
12
+ npm install @offscript/sdk
13
+ ```
14
+
15
+ ## Uso
16
+
17
+ ```ts
18
+ import { Offscript } from "@offscript/sdk";
19
+
20
+ const offscript = new Offscript({
21
+ apiUrl: "https://api.offscript.example",
22
+ platformId: "platform-id",
23
+ appVersion: "1.4.2",
24
+ recording: { rrweb: true, actions: true, http: true, console: true, errors: true },
25
+ privacy: { maskSensitiveInputs: true, captureRequestBodies: false, captureResponseBodies: false },
26
+ });
27
+
28
+ await offscript.init(); // retoma sessão persistida (reload / MPA), se houver
29
+ await offscript.startRecording({
30
+ testCaseId: "test-case-id",
31
+ executionId: "execution-id",
32
+ sessionToken: "short-lived-session-token", // emitido pelo SEU backend; nunca uma chave permanente
33
+ });
34
+ await offscript.pauseRecording(); // retomar gera um novo snapshot completo
35
+ await offscript.resumeRecording();
36
+ const summary = await offscript.stopRecording(); // { flushed, pendingEvents, completed }
37
+ await offscript.destroy();
38
+ ```
39
+
40
+ Todos os métodos são **idempotentes** (`init`, `startRecording` com a mesma execução, `stopRecording`, `pause/resume`, `destroy`). Chamadas concorrentes de `startRecording` compartilham a mesma promise; iniciar outra execução com uma ativa lança `InvalidStateError`.
41
+
42
+ ### Estados e eventos
43
+ `idle → initializing → recording ⇄ paused → stopping → stopped` (e `error`). `offscript.getState()` devolve `{ status, session, pending, lastError }`.
44
+
45
+ ```ts
46
+ offscript.on("statusChange", ({ from, to }) => …);
47
+ offscript.on("error", (e) => …); // OffscriptError tipado (e.code)
48
+ offscript.on("sessionStart" | "sessionEnd" | "flush" | "overflow" | "disabled", …);
49
+ ```
50
+ Erros tipados: `ConfigError`, `AuthError`, `SessionExpiredError`, `SessionDisabledError`, `InvalidStateError`, `TransportError` (todos estendem `OffscriptError` com `code`).
51
+
52
+ ### Autorização
53
+ A gravação só começa depois que `POST /sdk/sessions` autoriza o token e responde `recording.enabled: true`. O token é guardado só em `sessionStorage` (escopo da aba) e usado em `Authorization: Bearer`; renovações chegam em `sessionToken` nas respostas. O backend pode desativar remotamente via heartbeat.
54
+
55
+ ## Configuração
56
+
57
+ | Opção | Padrão | Descrição |
58
+ |---|---|---|
59
+ | `apiUrl` | — | HTTPS obrigatório (HTTP só em localhost) |
60
+ | `platformId` | — | Plataforma do SDK |
61
+ | `appVersion` | — | Versão/build da app, enviada no contexto |
62
+ | `autoResume` | `true` | Retoma sessão persistida em `init()` |
63
+ | `correlationWindowMs` | `3000` | Janela para ligar http/erros à ação anterior |
64
+ | `heartbeatIntervalMs` | `30000` | Usado se o backend não informar |
65
+ | `recording.rrweb/actions/http/console/errors/context/iframes` | `true` | Liga cada módulo |
66
+ | `recording.mouseMove` | `false` | Trajetória do mouse nas *ações* (rrweb já grava o movimento) |
67
+ | `recording.consoleLevels` | todos | `log`, `info`, `warn`, `error` |
68
+ | `recording.throttleMs` | `100` | Amostragem de mousemove |
69
+ | `recording.rrwebCheckoutEveryMs` | `300000` | Snapshot completo periódico (0 desliga) |
70
+ | `recording.rrwebRecordCanvas` | `false` | Canvas (custoso) |
71
+ | `recording.testIdAttributes` | `data-testid, data-test, data-cy, data-qa` | Atributos de teste para seletores |
72
+ | `recording.stableAttributes` | `name, data-id, aria-label` | Atributos estáveis extras |
73
+ | `privacy.maskSensitiveInputs` | `true` | Máscara de inputs no replay |
74
+ | `privacy.maskAllText` | `false` | Máscara de todo texto no replay |
75
+ | `privacy.captureRequestBodies / captureResponseBodies` | `false` | Bodies HTTP |
76
+ | `privacy.allowedInputSelectors` | `[data-offscript-allow]` | Campos cujo valor pode ser gravado |
77
+ | `privacy.blockSelectors / maskTextSelectors / ignoreSelectors` | `[data-offscript-block]`… | Bloquear, mascarar texto, ignorar ações |
78
+ | `privacy.ignoreUrls` | `[]` | Requisições não capturadas (string ou RegExp) |
79
+ | `privacy.redactHeaders / redactKeys` | `[]` | Extras além do padrão |
80
+ | `privacy.maxBodyBytes` | `16384` | Limite de body capturado |
81
+ | `privacy.localRetentionMs` | `86400000` | Retenção local de eventos não enviados |
82
+ | `transport.*` | ver `DEFAULT_TRANSPORT` | lote, flush, memória, retries, `compress` (gzip; requer suporte no backend), `persist` (IndexedDB) |
83
+
84
+ ### Privacidade (padrão seguro)
85
+ Senhas, tokens, `Authorization`, cookies, chaves de API, JWT, CPF/CNPJ e cartões (Luhn) são redigidos **antes** de persistir ou enviar — em headers, query, bodies, console, erros, URLs/atributos/textos do rrweb. Valores digitados não vão para as ações (viram `valueRef`) a não ser em campos com `data-offscript-allow`. Use `data-offscript-block` / `.offscript-block` para remover um elemento do replay e `data-offscript-ignore` para ignorar suas ações. Isso ajuda a atender a LGPD, mas **não a substitui**: a base legal, o aviso aos testadores, a retenção e a exclusão no servidor são responsabilidade da Offscript/cliente.
86
+
87
+ ## Adaptadores
88
+ `@offscript/sdk/vue` (Vue 2/3, sem importar Vue), `@offscript/sdk/nuxt` (client-only), `@offscript/sdk/vanilla` (`createOffscript`, `startOffscript`). Exemplos em [examples/](./examples).
89
+
90
+ ## Playwright
91
+ `offscript.exportPlaywrightData()` ou `buildPlaywrightContract()` (de `@offscript/sdk/playwright`) — ver [docs/playwright-contract.md](./docs/playwright-contract.md). O SDK não executa Playwright.
92
+
93
+ ## Documentação
94
+ - [Arquitetura e decisões](./docs/architecture.md)
95
+ - [Contrato da API](./docs/api-contract.md) — **o backend da Offscript precisa implementá-lo; este repositório só traz um servidor de referência de testes**
96
+ - [Contrato de eventos](./docs/event-contract.md)
97
+ - [Contrato Playwright](./docs/playwright-contract.md)
98
+
99
+ ## Limitações conhecidas
100
+ - **Iframes cross-origin (ex.: seats.io)**: nem o SDK nem o rrweb acessam o conteúdo interno. São registrados presença (`origin` + `path`, sem query), dimensões, posição, foco (quando observável) e interações visíveis na página principal. Caminhos futuros: instrumentação/eventos públicos do seats.io, ou captura complementar via Playwright em ambiente de teste autorizado — **não implementados**.
101
+ - **HTTP**: só `fetch` e `XMLHttpRequest` da página principal. Não captura WebSocket, requisições de iframes cross-origin, Service Workers, cookies HttpOnly, headers protegidos, nem `fetch` chamado antes do SDK iniciar. `duration` do fetch é até os headers. Bodies de streaming/binário são omitidos. Bodies de request do tipo `Request`/stream não são lidos.
102
+ - **Console**: o stack aponta para o wrapper; arquivo/linha de `console.*` não é o da chamada original no DevTools.
103
+ - **Entrega ao fechar a aba**: usa `fetch keepalive` (≤ 60 KB) sem ACK; o que não chegar é reenviado na próxima página da mesma aba. Se o navegador for encerrado abruptamente (crash, fechamento da última aba), **não há garantia de entrega** — eventos pendentes ficam no IndexedDB até a próxima sessão da aba/origem ou expirarem.
104
+ - **Multi-aba**: gravação por aba (cada uma com `tabId` e sequência próprios). A detecção de aba clonada exige `navigator.locks`.
105
+ - **Replay**: só reproduz o DOM gravado (iframe sandbox sem scripts). Canvas é opcional e custoso; vídeo/áudio e Shadow DOM fechado seguem as limitações do rrweb. `mousemove` sofre amostragem.
106
+ - **Backpressure**: com a fila cheia, eventos de baixa prioridade são descartados (`overflow`) e o SDK força novo snapshot rrweb.
107
+ - O `exportPlaywrightData()` do navegador cobre as ações da página atual (memória, até 5000); para a sessão inteira use `buildPlaywrightContract` com os eventos armazenados no backend.
108
+ - **Não verificado**: execução em aplicações Vue/Nuxt/Laravel/Inertia reais, navegadores além do Chromium, Safari/iOS (limites de `keepalive`/IndexedDB), carga em páginas muito grandes (só há métricas internas `getMetrics()`, sem benchmark).
109
+
110
+ ## Desenvolvimento
111
+
112
+ ```bash
113
+ npm install
114
+ npm run typecheck
115
+ npm test # 69 testes (vitest + jsdom + servidor HTTP de referência real)
116
+ npm run test:e2e # Playwright em Chromium real (npx playwright install chromium)
117
+ npm run build # tsup (ESM+CJS) + tsc (declarações)
118
+ ```
119
+
120
+ ### Testes
121
+ | Suite | Cobertura |
122
+ |---|---|
123
+ | `tests/session` | init, token inválido, desativação remota, idempotência, pausa/retomada, reload, sessão expirada, heartbeat, 401 no envio |
124
+ | `tests/transport` | lotes ordenados, ACK, falha 5xx + backoff, persistência/recuperação, idempotência, 413, backpressure, flush final, offline/online, gzip |
125
+ | `tests/rrweb` | snapshot, mutações, máscara de inputs, redação de URLs, pausa+snapshot, **replay** com `Replayer` |
126
+ | `tests/actions` | click, input, select, checkbox, teclado, scroll, hover, drag, SPA, seletores |
127
+ | `tests/http` | fetch ok/erro/abort/concorrente/grande/binário, XHR, sanitização, exclusão da própria API, correlação, remoção segura |
128
+ | `tests/observability` | console, recursão, erros globais, correlação, contexto, iframe seats.io |
129
+ | `tests/playwright` | normalização, contrato, validação, SelectorGenerator |
130
+ | `tests/compat` | MPA com reload, SPA/Inertia, multi-aba, adaptadores Vue/Nuxt/vanilla, falha de recorder, destroy |
131
+ | `e2e/mpa.spec.ts` | **Chromium real**: gravação com navegação MPA + reload + SPA, privacidade, correlação, contrato, replay completo no player rrweb |
132
+
133
+ ### Publicação
134
+ Versionamento semântico (`MAJOR.MINOR.PATCH`); mudanças incompatíveis nos contratos de evento/Playwright incrementam o `schemaVersion`/`contractVersion` major. Fluxo: `npm version <patch|minor|major>` → `npm run verify` → `npm publish --access public` (o `prepublishOnly` já roda typecheck, testes e build).
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ var chunk3NX2AGXM_cjs = require('../chunk-3NX2AGXM.cjs');
4
+ require('../chunk-B6GO5FE5.cjs');
5
+
6
+ // src/adapters/nuxt.ts
7
+ function createNuxtOffscript(config) {
8
+ if (typeof window === "undefined") return null;
9
+ const sdk = new chunk3NX2AGXM_cjs.Offscript(config);
10
+ void sdk.init().catch(() => void 0);
11
+ return sdk;
12
+ }
13
+
14
+ exports.createNuxtOffscript = createNuxtOffscript;
15
+ //# sourceMappingURL=nuxt.cjs.map
16
+ //# sourceMappingURL=nuxt.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/adapters/nuxt.ts"],"names":["Offscript"],"mappings":";;;;;;AAUO,SAAS,oBAAoB,MAAA,EAA2C;AAC7E,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,IAAA;AAC1C,EAAA,MAAM,GAAA,GAAM,IAAIA,2BAAA,CAAU,MAAM,CAAA;AAChC,EAAA,KAAK,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AACrC,EAAA,OAAO,GAAA;AACT","file":"nuxt.cjs","sourcesContent":["import { Offscript } from \"../core/OffscriptSDK\";\nimport type { OffscriptConfig } from \"../types/config\";\n\n/**\n * Uso em plugin client-only do Nuxt (plugins/offscript.client.ts):\n *\n * export default defineNuxtPlugin(() => ({ provide: { offscript: createNuxtOffscript({...}) } }))\n *\n * Retorna null no servidor (SSR) para que nada seja instanciado fora do navegador.\n */\nexport function createNuxtOffscript(config: OffscriptConfig): Offscript | null {\n if (typeof window === \"undefined\") return null;\n const sdk = new Offscript(config);\n void sdk.init().catch(() => undefined);\n return sdk;\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import { Offscript } from "../core/OffscriptSDK";
2
+ import type { OffscriptConfig } from "../types/config";
3
+ /**
4
+ * Uso em plugin client-only do Nuxt (plugins/offscript.client.ts):
5
+ *
6
+ * export default defineNuxtPlugin(() => ({ provide: { offscript: createNuxtOffscript({...}) } }))
7
+ *
8
+ * Retorna null no servidor (SSR) para que nada seja instanciado fora do navegador.
9
+ */
10
+ export declare function createNuxtOffscript(config: OffscriptConfig): Offscript | null;
@@ -0,0 +1,14 @@
1
+ import { Offscript } from '../chunk-3OSCH7J2.js';
2
+ import '../chunk-LFXHB4PN.js';
3
+
4
+ // src/adapters/nuxt.ts
5
+ function createNuxtOffscript(config) {
6
+ if (typeof window === "undefined") return null;
7
+ const sdk = new Offscript(config);
8
+ void sdk.init().catch(() => void 0);
9
+ return sdk;
10
+ }
11
+
12
+ export { createNuxtOffscript };
13
+ //# sourceMappingURL=nuxt.js.map
14
+ //# sourceMappingURL=nuxt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/adapters/nuxt.ts"],"names":[],"mappings":";;;;AAUO,SAAS,oBAAoB,MAAA,EAA2C;AAC7E,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,IAAA;AAC1C,EAAA,MAAM,GAAA,GAAM,IAAI,SAAA,CAAU,MAAM,CAAA;AAChC,EAAA,KAAK,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AACrC,EAAA,OAAO,GAAA;AACT","file":"nuxt.js","sourcesContent":["import { Offscript } from \"../core/OffscriptSDK\";\nimport type { OffscriptConfig } from \"../types/config\";\n\n/**\n * Uso em plugin client-only do Nuxt (plugins/offscript.client.ts):\n *\n * export default defineNuxtPlugin(() => ({ provide: { offscript: createNuxtOffscript({...}) } }))\n *\n * Retorna null no servidor (SSR) para que nada seja instanciado fora do navegador.\n */\nexport function createNuxtOffscript(config: OffscriptConfig): Offscript | null {\n if (typeof window === \"undefined\") return null;\n const sdk = new Offscript(config);\n void sdk.init().catch(() => undefined);\n return sdk;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var chunkHAPNSHFG_cjs = require('../chunk-HAPNSHFG.cjs');
4
+ require('../chunk-3NX2AGXM.cjs');
5
+ require('../chunk-B6GO5FE5.cjs');
6
+
7
+
8
+
9
+ Object.defineProperty(exports, "createOffscript", {
10
+ enumerable: true,
11
+ get: function () { return chunkHAPNSHFG_cjs.createOffscript; }
12
+ });
13
+ Object.defineProperty(exports, "startOffscript", {
14
+ enumerable: true,
15
+ get: function () { return chunkHAPNSHFG_cjs.startOffscript; }
16
+ });
17
+ //# sourceMappingURL=vanilla.cjs.map
18
+ //# sourceMappingURL=vanilla.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"vanilla.cjs"}
@@ -0,0 +1,6 @@
1
+ import { Offscript } from "../core/OffscriptSDK";
2
+ import type { OffscriptConfig } from "../types/config";
3
+ import type { StartRecordingOptions } from "../types/session";
4
+ /** Atalho para aplicações JS tradicionais, Blade e MPA: inicializa e retoma sessões persistidas. */
5
+ export declare function createOffscript(config: OffscriptConfig): Promise<Offscript>;
6
+ export declare function startOffscript(config: OffscriptConfig, start: StartRecordingOptions): Promise<Offscript>;
@@ -0,0 +1,5 @@
1
+ export { createOffscript, startOffscript } from '../chunk-MBYNQSKA.js';
2
+ import '../chunk-3OSCH7J2.js';
3
+ import '../chunk-LFXHB4PN.js';
4
+ //# sourceMappingURL=vanilla.js.map
5
+ //# sourceMappingURL=vanilla.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"vanilla.js"}
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ var chunk3NX2AGXM_cjs = require('../chunk-3NX2AGXM.cjs');
4
+ require('../chunk-B6GO5FE5.cjs');
5
+
6
+ // src/adapters/vue.ts
7
+ var OFFSCRIPT_KEY = "$offscript";
8
+ var OffscriptPlugin = {
9
+ install(app, config) {
10
+ const sdk = new chunk3NX2AGXM_cjs.Offscript(config);
11
+ void sdk.init().catch(() => void 0);
12
+ if (app.config?.globalProperties) {
13
+ app.config.globalProperties[OFFSCRIPT_KEY] = sdk;
14
+ app.provide?.(OFFSCRIPT_KEY, sdk);
15
+ } else if (app.prototype) {
16
+ app.prototype[OFFSCRIPT_KEY] = sdk;
17
+ }
18
+ }
19
+ };
20
+
21
+ exports.OFFSCRIPT_KEY = OFFSCRIPT_KEY;
22
+ exports.OffscriptPlugin = OffscriptPlugin;
23
+ //# sourceMappingURL=vue.cjs.map
24
+ //# sourceMappingURL=vue.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/adapters/vue.ts"],"names":["Offscript"],"mappings":";;;;;;AAGO,IAAM,aAAA,GAAgB;AAatB,IAAM,eAAA,GAAkB;AAAA,EAC7B,OAAA,CAAQ,KAAiB,MAAA,EAA+B;AACtD,IAAA,MAAM,GAAA,GAAM,IAAIA,2BAAA,CAAU,MAAM,CAAA;AAEhC,IAAA,KAAK,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AACrC,IAAA,IAAI,GAAA,CAAI,QAAQ,gBAAA,EAAkB;AAChC,MAAA,GAAA,CAAI,MAAA,CAAO,gBAAA,CAAiB,aAAa,CAAA,GAAI,GAAA;AAC7C,MAAA,GAAA,CAAI,OAAA,GAAU,eAAe,GAAG,CAAA;AAAA,IAClC,CAAA,MAAA,IAAW,IAAI,SAAA,EAAW;AACxB,MAAA,GAAA,CAAI,SAAA,CAAU,aAAa,CAAA,GAAI,GAAA;AAAA,IACjC;AAAA,EACF;AACF","file":"vue.cjs","sourcesContent":["import { Offscript } from \"../core/OffscriptSDK\";\nimport type { OffscriptConfig } from \"../types/config\";\n\nexport const OFFSCRIPT_KEY = \"$offscript\";\n\ninterface VueAppLike {\n config?: { globalProperties?: Record<string, unknown> };\n provide?: (key: string, value: unknown) => void;\n mixin?: (m: unknown) => void;\n prototype?: Record<string, unknown>;\n}\n\n/**\n * Plugin Vue 3 (app.use) e Vue 2 (Vue.use). Não importa Vue: funciona via duck typing.\n * A gravação não é iniciada automaticamente; chame `this.$offscript.startRecording(...)`.\n */\nexport const OffscriptPlugin = {\n install(app: VueAppLike, config: OffscriptConfig): void {\n const sdk = new Offscript(config);\n // init assíncrono: erros ficam disponíveis via sdk.on('error')\n void sdk.init().catch(() => undefined);\n if (app.config?.globalProperties) {\n app.config.globalProperties[OFFSCRIPT_KEY] = sdk; // Vue 3\n app.provide?.(OFFSCRIPT_KEY, sdk);\n } else if (app.prototype) {\n app.prototype[OFFSCRIPT_KEY] = sdk; // Vue 2 (Vue.use(OffscriptPlugin, config) passa o construtor)\n }\n },\n};\n"]}
@@ -0,0 +1,18 @@
1
+ import type { OffscriptConfig } from "../types/config";
2
+ export declare const OFFSCRIPT_KEY = "$offscript";
3
+ interface VueAppLike {
4
+ config?: {
5
+ globalProperties?: Record<string, unknown>;
6
+ };
7
+ provide?: (key: string, value: unknown) => void;
8
+ mixin?: (m: unknown) => void;
9
+ prototype?: Record<string, unknown>;
10
+ }
11
+ /**
12
+ * Plugin Vue 3 (app.use) e Vue 2 (Vue.use). Não importa Vue: funciona via duck typing.
13
+ * A gravação não é iniciada automaticamente; chame `this.$offscript.startRecording(...)`.
14
+ */
15
+ export declare const OffscriptPlugin: {
16
+ install(app: VueAppLike, config: OffscriptConfig): void;
17
+ };
18
+ export {};
@@ -0,0 +1,21 @@
1
+ import { Offscript } from '../chunk-3OSCH7J2.js';
2
+ import '../chunk-LFXHB4PN.js';
3
+
4
+ // src/adapters/vue.ts
5
+ var OFFSCRIPT_KEY = "$offscript";
6
+ var OffscriptPlugin = {
7
+ install(app, config) {
8
+ const sdk = new Offscript(config);
9
+ void sdk.init().catch(() => void 0);
10
+ if (app.config?.globalProperties) {
11
+ app.config.globalProperties[OFFSCRIPT_KEY] = sdk;
12
+ app.provide?.(OFFSCRIPT_KEY, sdk);
13
+ } else if (app.prototype) {
14
+ app.prototype[OFFSCRIPT_KEY] = sdk;
15
+ }
16
+ }
17
+ };
18
+
19
+ export { OFFSCRIPT_KEY, OffscriptPlugin };
20
+ //# sourceMappingURL=vue.js.map
21
+ //# sourceMappingURL=vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/adapters/vue.ts"],"names":[],"mappings":";;;;AAGO,IAAM,aAAA,GAAgB;AAatB,IAAM,eAAA,GAAkB;AAAA,EAC7B,OAAA,CAAQ,KAAiB,MAAA,EAA+B;AACtD,IAAA,MAAM,GAAA,GAAM,IAAI,SAAA,CAAU,MAAM,CAAA;AAEhC,IAAA,KAAK,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AACrC,IAAA,IAAI,GAAA,CAAI,QAAQ,gBAAA,EAAkB;AAChC,MAAA,GAAA,CAAI,MAAA,CAAO,gBAAA,CAAiB,aAAa,CAAA,GAAI,GAAA;AAC7C,MAAA,GAAA,CAAI,OAAA,GAAU,eAAe,GAAG,CAAA;AAAA,IAClC,CAAA,MAAA,IAAW,IAAI,SAAA,EAAW;AACxB,MAAA,GAAA,CAAI,SAAA,CAAU,aAAa,CAAA,GAAI,GAAA;AAAA,IACjC;AAAA,EACF;AACF","file":"vue.js","sourcesContent":["import { Offscript } from \"../core/OffscriptSDK\";\nimport type { OffscriptConfig } from \"../types/config\";\n\nexport const OFFSCRIPT_KEY = \"$offscript\";\n\ninterface VueAppLike {\n config?: { globalProperties?: Record<string, unknown> };\n provide?: (key: string, value: unknown) => void;\n mixin?: (m: unknown) => void;\n prototype?: Record<string, unknown>;\n}\n\n/**\n * Plugin Vue 3 (app.use) e Vue 2 (Vue.use). Não importa Vue: funciona via duck typing.\n * A gravação não é iniciada automaticamente; chame `this.$offscript.startRecording(...)`.\n */\nexport const OffscriptPlugin = {\n install(app: VueAppLike, config: OffscriptConfig): void {\n const sdk = new Offscript(config);\n // init assíncrono: erros ficam disponíveis via sdk.on('error')\n void sdk.init().catch(() => undefined);\n if (app.config?.globalProperties) {\n app.config.globalProperties[OFFSCRIPT_KEY] = sdk; // Vue 3\n app.provide?.(OFFSCRIPT_KEY, sdk);\n } else if (app.prototype) {\n app.prototype[OFFSCRIPT_KEY] = sdk; // Vue 2 (Vue.use(OffscriptPlugin, config) passa o construtor)\n }\n },\n};\n"]}