@camada/deno 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -6,12 +6,10 @@ page and beacon, records the outcomes your handler knows (`track()`), and ships
6
6
  batches off the response path. A thin binding over `@camada/core/fetch`, the pipeline every
7
7
  Web-fetch adapter shares. Fails open by design — a camada outage or bug never 5xxes your app.
8
8
 
9
- Not yet on npm — consumed via a `file:` dependency from a sibling checkout. Built with tsup like
10
- the rest of the workspace; there is no `deno.json` this round. From Deno, once published it is
11
- `npm:@camada/deno`; locally, an import-map entry pointing at the sibling build works:
9
+ Published to npm (there is no JSR package yet). Import it with the `npm:` specifier, or map it once:
12
10
 
13
11
  ```json
14
- { "imports": { "@camada/deno": "../camada-deno/dist/index.js" } }
12
+ { "imports": { "@camada/deno": "npm:@camada/deno" } }
15
13
  ```
16
14
 
17
15
  ## Quickstart
@@ -68,7 +66,9 @@ secret. Without `CAMADA_KEY` the wrapper is inert (one log line, no requests, no
68
66
  7. Otherwise your handler runs; the settled response ships one batched, redacted event with its
69
67
  real status. A handler that throws ships `st: 500` — what `Deno.serve` answers for it — and
70
68
  rethrows (an `onError` answering with another status is not seen here). A first visit is given the `_sfp` session
71
- cookie (appended even to a `Response.redirect()`, whose headers are immutable).
69
+ cookie (appended even to a `Response.redirect()`, whose headers are immutable). A WebSocket upgrade is the
70
+ exception: the `101` from `Deno.upgradeWebSocket()` goes back untouched, with no cookie, and ships `st` 101.
71
+ Deno before 2.6 stops `Deno.serve` if an upgrade response is copied.
72
72
 
73
73
  ## Options
74
74
 
package/dist/index.cjs CHANGED
@@ -44,7 +44,7 @@ var import_fetch = require("@camada/core/fetch");
44
44
 
45
45
  // package.json
46
46
  var name = "@camada/deno";
47
- var version = "0.1.1";
47
+ var version = "0.1.3";
48
48
 
49
49
  // src/version.ts
50
50
  var SDK_ID = `${name}/${version}`;
@@ -84,8 +84,11 @@ function camada(opts = {}) {
84
84
  cam.after(req, r.vars, 500);
85
85
  throw err;
86
86
  }
87
- cam.after(req, r.vars, res.status);
88
- return r.vars.sessionCookie ? (0, import_fetch.withSetCookie)(res, r.vars.sessionCookie) : res;
87
+ if (res.status === 101) {
88
+ cam.after(req, r.vars, 101);
89
+ return res;
90
+ }
91
+ return cam.finish(req, r.vars, r.vars.sessionCookie ? (0, import_fetch.withSetCookie)(res, r.vars.sessionCookie) : res);
89
92
  };
90
93
  }
91
94
  var track = (req, event, data) => (0, import_fetch.track)(slots.get(req), event, data);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/camada.ts","../package.json","../src/version.ts"],"sourcesContent":["// @camada/deno — the one-line install for a Deno.serve app:\n// Deno.serve(camada()(handler)); // env: CAMADA_KEY (+ CAMADA_INGEST_URL / CAMADA_SNAPSHOT_URL in dev)\n// new Response(`<head>${scriptTag(req)}</head>…`) // the first-party beacon\n// track(req, 'login_failed', { user }) // an outcome the wire cannot show\nexport {\n camada, track, scriptTag, resetCamada,\n type CamadaDenoOptions, type CamadaDenoVars, type ServeHandlerInfo, type ServeHandler, type WrappedHandler,\n} from './camada.js';\n","// @camada/deno — the Deno.serve wrapper over @camada/core/fetch (SDK-G04).\n// Deno.serve(camada()(handler));\n// The runtime vouches for exactly one thing here: `info.remoteAddr`, the TCP socket peer. It goes\n// in as `ctx.peer` and core combines it with X-Forwarded-For under the trusted-proxy rules; a\n// client header on its own never becomes the ip. Deno is a long-lived process, so the snapshot\n// polls on a timer by default (CAMADA_SERVERLESS=1 or `mode: 'lazy'` for Deno Deploy), and there\n// is no `waitUntil`: the event flush is a fire-and-forget promise the process keeps alive.\nimport iife from '@camada/browser/iife-string';\nimport { TAP_DENO, logRateLimited } from '@camada/core';\nimport { createFetchCamada, withSetCookie, track as coreTrack, scriptTag as coreScriptTag, type FetchCamada, type FetchCamadaOptions, type FetchVars } from '@camada/core/fetch';\nimport { SDK_ID } from './version.js';\n\nexport type CamadaDenoOptions = FetchCamadaOptions;\nexport type CamadaDenoVars = FetchVars;\n\n/** The second argument Deno.serve hands a handler, typed structurally so this package needs no Deno types. */\nexport interface ServeHandlerInfo {\n remoteAddr: { transport: 'tcp' | 'udp' | 'unix' | 'unixpacket'; hostname?: string; port?: number };\n}\nexport type ServeHandler = (req: Request, info: ServeHandlerInfo) => Response | Promise<Response>;\nexport type WrappedHandler = (req: Request, info: ServeHandlerInfo) => Promise<Response>;\n\ntype DenoGlobal = { env: { get(name: string): string | undefined } };\ntype Env = Record<string, string | undefined>;\n\n// Every camada() call owns one pipeline; resetCamada() must reach all of them.\nconst instances = new Set<FetchCamada>();\n// The per-request slot: Deno hands the same Request object to the handler, so track() and\n// scriptTag() find their vars by it without the app threading anything through.\nconst slots = new WeakMap<Request, FetchVars>();\n\n/** Every key core reads, fetched one by one: `Deno.env.get` works under a granular\n * `--allow-env=CAMADA_KEY,…` grant, where `toObject()` (and enumerating `process.env`) throws. */\nconst ENV_KEYS = ['CAMADA_KEY', 'CAMADA_TOKEN', 'CAMADA_SNAPSHOT_TOKEN', 'CAMADA_INGEST_URL', 'CAMADA_SNAPSHOT_URL', 'CAMADA_TRUSTED_PROXY', 'CAMADA_CHALLENGE', 'CAMADA_DISABLED', 'CAMADA_SERVERLESS'];\n\n/** Deno.env where there is a Deno (a Node test process has only process.env). A key the grant does\n * not cover throws NotCapable; that costs enforcement, never the response, and is logged as what it is. */\nfunction hostEnv(): Env | undefined {\n const deno = (globalThis as { Deno?: DenoGlobal }).Deno;\n if (!deno) return globalThis.process?.env;\n const env: Env = {};\n let denied = 0;\n for (const k of ENV_KEYS) {\n try { env[k] = deno.env.get(k); } catch { denied++; }\n }\n if (denied === ENV_KEYS.length) logRateLimited(new Error('Deno.env access denied — run with --allow-env (or --allow-env=CAMADA_KEY,CAMADA_INGEST_URL,CAMADA_SNAPSHOT_URL); camada is inactive'));\n return env;\n}\n\n/** Only a TCP peer is an address; a unix socket has none, and camada then sees no client ip. */\nconst peerOf = (info: ServeHandlerInfo | undefined): string | null =>\n info?.remoteAddr?.transport === 'tcp' ? info.remoteAddr.hostname ?? null : null;\n\n/**\n * Builds the wrapper: `Deno.serve(camada()(handler))`. Mode defaults to `timer` (a long-lived\n * process polls the snapshot on an unref'd interval); `opts.mode` overrides and CAMADA_SERVERLESS=1\n * forces lazy. Deno's setInterval returns a number, so that unref is a no-op there and the poll\n * keeps the process alive until resetCamada() or exit — under Node (vitest) resetCamada() is what\n * lets a test process end.\n */\nexport function camada(opts: CamadaDenoOptions = {}): (handler: ServeHandler) => WrappedHandler {\n const cam = createFetchCamada({ tap: TAP_DENO, sdk: SDK_ID, iife }, { ...opts, mode: opts.mode ?? 'timer' });\n instances.add(cam);\n return (handler) => async (req, info) => {\n const r = await cam.before(req, { peer: peerOf(info), env: hostEnv() });\n if (!r) return handler(req, info);\n if (r.response) return r.response;\n slots.set(req, r.vars);\n let res: Response;\n try {\n res = await handler(req, info);\n } catch (err) {\n cam.after(req, r.vars, 500); // Deno.serve answers 500 for a thrown handler (an onError returning its own status is not visible here)\n throw err;\n }\n cam.after(req, r.vars, res.status);\n return r.vars.sessionCookie ? withSetCookie(res, r.vars.sessionCookie) : res;\n };\n}\n\n/** Records an outcome the handler knows (`login_failed`, `signup`, ...), joined to this request's\n * event. Never throws; a silent no-op where the wrapper did not run. See @camada/core/fetch. */\nexport const track = (req: Request, event: string, data?: { user?: string }): Promise<void> => coreTrack(slots.get(req), event, data);\n\n/** The `<script>` tag for an HTML response; `''` where the wrapper did not run or the beacon is off. */\nexport const scriptTag = (req: Request): string => coreScriptTag(slots.get(req));\n\n/** Test/reset hook: stops every poller and queue this module created and drops their engines; the wrappers stay wired and rebuild lazily. */\nexport function resetCamada(): void {\n for (const cam of instances) cam.reset();\n}\n","{\n \"name\": \"@camada/deno\",\n \"version\": \"0.1.1\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=20\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"check\": \"tsc --noEmit\"\n },\n \"description\": \"camada SDK for Deno.serve: snapshot enforcement, first-party challenge and beacon, track() outcomes, timer-polled snapshot and batched event shipping\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"dependencies\": {\n \"@camada/core\": \"file:../camada-core\",\n \"@camada/browser\": \"file:../camada-browser\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.10.0\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.7.2\",\n \"vitest\": \"^3.0.0\"\n }\n}\n","// The SDK's wire identity (SDK-03): x-camada-sdk: <package>/<version>. Named JSON imports are\n// inlined and tree-shaken by tsup at build, so dist carries two literals — no runtime fs read.\nimport { name, version } from '../package.json';\nexport const SDK_ID = `${name}/${version}`;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACOA,yBAAiB;AACjB,kBAAyC;AACzC,mBAA4J;;;ACR1J,WAAQ;AACR,cAAW;;;ACCN,IAAM,SAAS,GAAG,IAAI,IAAI,OAAO;;;AFuBxC,IAAM,YAAY,oBAAI,IAAiB;AAGvC,IAAM,QAAQ,oBAAI,QAA4B;AAI9C,IAAM,WAAW,CAAC,cAAc,gBAAgB,yBAAyB,qBAAqB,uBAAuB,wBAAwB,oBAAoB,mBAAmB,mBAAmB;AAIvM,SAAS,UAA2B;AAClC,QAAM,OAAQ,WAAqC;AACnD,MAAI,CAAC,KAAM,QAAO,WAAW,SAAS;AACtC,QAAM,MAAW,CAAC;AAClB,MAAI,SAAS;AACb,aAAW,KAAK,UAAU;AACxB,QAAI;AAAE,UAAI,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC;AAAA,IAAG,QAAQ;AAAE;AAAA,IAAU;AAAA,EACtD;AACA,MAAI,WAAW,SAAS,OAAQ,iCAAe,IAAI,MAAM,0IAAqI,CAAC;AAC/L,SAAO;AACT;AAGA,IAAM,SAAS,CAAC,SACd,MAAM,YAAY,cAAc,QAAQ,KAAK,WAAW,YAAY,OAAO;AAStE,SAAS,OAAO,OAA0B,CAAC,GAA8C;AAC9F,QAAM,UAAM,gCAAkB,EAAE,KAAK,sBAAU,KAAK,QAAQ,yBAAAA,QAAK,GAAG,EAAE,GAAG,MAAM,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAC3G,YAAU,IAAI,GAAG;AACjB,SAAO,CAAC,YAAY,OAAO,KAAK,SAAS;AACvC,UAAM,IAAI,MAAM,IAAI,OAAO,KAAK,EAAE,MAAM,OAAO,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;AACtE,QAAI,CAAC,EAAG,QAAO,QAAQ,KAAK,IAAI;AAChC,QAAI,EAAE,SAAU,QAAO,EAAE;AACzB,UAAM,IAAI,KAAK,EAAE,IAAI;AACrB,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,QAAQ,KAAK,IAAI;AAAA,IAC/B,SAAS,KAAK;AACZ,UAAI,MAAM,KAAK,EAAE,MAAM,GAAG;AAC1B,YAAM;AAAA,IACR;AACA,QAAI,MAAM,KAAK,EAAE,MAAM,IAAI,MAAM;AACjC,WAAO,EAAE,KAAK,oBAAgB,4BAAc,KAAK,EAAE,KAAK,aAAa,IAAI;AAAA,EAC3E;AACF;AAIO,IAAM,QAAQ,CAAC,KAAc,OAAe,aAA4C,aAAAC,OAAU,MAAM,IAAI,GAAG,GAAG,OAAO,IAAI;AAG7H,IAAM,YAAY,CAAC,YAAyB,aAAAC,WAAc,MAAM,IAAI,GAAG,CAAC;AAGxE,SAAS,cAAoB;AAClC,aAAW,OAAO,UAAW,KAAI,MAAM;AACzC;","names":["iife","coreTrack","coreScriptTag"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/camada.ts","../package.json","../src/version.ts"],"sourcesContent":["// @camada/deno — the one-line install for a Deno.serve app:\n// Deno.serve(camada()(handler)); // env: CAMADA_KEY (+ CAMADA_INGEST_URL / CAMADA_SNAPSHOT_URL in dev)\n// new Response(`<head>${scriptTag(req)}</head>…`) // the first-party beacon\n// track(req, 'login_failed', { user }) // an outcome the wire cannot show\nexport {\n camada, track, scriptTag, resetCamada,\n type CamadaDenoOptions, type CamadaDenoVars, type ServeHandlerInfo, type ServeHandler, type WrappedHandler,\n} from './camada.js';\n","// @camada/deno — the Deno.serve wrapper over @camada/core/fetch (SDK-G04).\n// Deno.serve(camada()(handler));\n// The runtime vouches for exactly one thing here: `info.remoteAddr`, the TCP socket peer. It goes\n// in as `ctx.peer` and core combines it with X-Forwarded-For under the trusted-proxy rules; a\n// client header on its own never becomes the ip. Deno is a long-lived process, so the snapshot\n// polls on a timer by default (CAMADA_SERVERLESS=1 or `mode: 'lazy'` for Deno Deploy), and there\n// is no `waitUntil`: the event flush is a fire-and-forget promise the process keeps alive.\nimport iife from '@camada/browser/iife-string';\nimport { TAP_DENO, logRateLimited } from '@camada/core';\nimport { createFetchCamada, withSetCookie, track as coreTrack, scriptTag as coreScriptTag, type FetchCamada, type FetchCamadaOptions, type FetchVars } from '@camada/core/fetch';\nimport { SDK_ID } from './version.js';\n\nexport type CamadaDenoOptions = FetchCamadaOptions;\nexport type CamadaDenoVars = FetchVars;\n\n/** The second argument Deno.serve hands a handler, typed structurally so this package needs no Deno types. */\nexport interface ServeHandlerInfo {\n remoteAddr: { transport: 'tcp' | 'udp' | 'unix' | 'unixpacket'; hostname?: string; port?: number };\n}\nexport type ServeHandler = (req: Request, info: ServeHandlerInfo) => Response | Promise<Response>;\nexport type WrappedHandler = (req: Request, info: ServeHandlerInfo) => Promise<Response>;\n\ntype DenoGlobal = { env: { get(name: string): string | undefined } };\ntype Env = Record<string, string | undefined>;\n\n// Every camada() call owns one pipeline; resetCamada() must reach all of them.\nconst instances = new Set<FetchCamada>();\n// The per-request slot: Deno hands the same Request object to the handler, so track() and\n// scriptTag() find their vars by it without the app threading anything through.\nconst slots = new WeakMap<Request, FetchVars>();\n\n/** Every key core reads, fetched one by one: `Deno.env.get` works under a granular\n * `--allow-env=CAMADA_KEY,…` grant, where `toObject()` (and enumerating `process.env`) throws. */\nconst ENV_KEYS = ['CAMADA_KEY', 'CAMADA_TOKEN', 'CAMADA_SNAPSHOT_TOKEN', 'CAMADA_INGEST_URL', 'CAMADA_SNAPSHOT_URL', 'CAMADA_TRUSTED_PROXY', 'CAMADA_CHALLENGE', 'CAMADA_DISABLED', 'CAMADA_SERVERLESS'];\n\n/** Deno.env where there is a Deno (a Node test process has only process.env). A key the grant does\n * not cover throws NotCapable; that costs enforcement, never the response, and is logged as what it is. */\nfunction hostEnv(): Env | undefined {\n const deno = (globalThis as { Deno?: DenoGlobal }).Deno;\n if (!deno) return globalThis.process?.env;\n const env: Env = {};\n let denied = 0;\n for (const k of ENV_KEYS) {\n try { env[k] = deno.env.get(k); } catch { denied++; }\n }\n if (denied === ENV_KEYS.length) logRateLimited(new Error('Deno.env access denied — run with --allow-env (or --allow-env=CAMADA_KEY,CAMADA_INGEST_URL,CAMADA_SNAPSHOT_URL); camada is inactive'));\n return env;\n}\n\n/** Only a TCP peer is an address; a unix socket has none, and camada then sees no client ip. */\nconst peerOf = (info: ServeHandlerInfo | undefined): string | null =>\n info?.remoteAddr?.transport === 'tcp' ? info.remoteAddr.hostname ?? null : null;\n\n/**\n * Builds the wrapper: `Deno.serve(camada()(handler))`. Mode defaults to `timer` (a long-lived\n * process polls the snapshot on an unref'd interval); `opts.mode` overrides and CAMADA_SERVERLESS=1\n * forces lazy. Deno's setInterval returns a number, so that unref is a no-op there and the poll\n * keeps the process alive until resetCamada() or exit — under Node (vitest) resetCamada() is what\n * lets a test process end.\n */\nexport function camada(opts: CamadaDenoOptions = {}): (handler: ServeHandler) => WrappedHandler {\n const cam = createFetchCamada({ tap: TAP_DENO, sdk: SDK_ID, iife }, { ...opts, mode: opts.mode ?? 'timer' });\n instances.add(cam);\n return (handler) => async (req, info) => {\n const r = await cam.before(req, { peer: peerOf(info), env: hostEnv() });\n if (!r) return handler(req, info);\n if (r.response) return r.response;\n slots.set(req, r.vars);\n let res: Response;\n try {\n res = await handler(req, info);\n } catch (err) {\n cam.after(req, r.vars, 500); // Deno.serve answers 500 for a thrown handler (an onError returning its own status is not visible here)\n throw err;\n }\n // A WebSocket upgrade must go back as the very Response Deno.upgradeWebSocket made: Deno < 2.6 stops\n // Deno.serve over a copy, and its headers are immutable, so it gets no session cookie. It has no body to time.\n if (res.status === 101) {\n cam.after(req, r.vars, 101);\n return res;\n }\n return cam.finish(req, r.vars, r.vars.sessionCookie ? withSetCookie(res, r.vars.sessionCookie) : res); // ships once the body has gone out\n };\n}\n\n/** Records an outcome the handler knows (`login_failed`, `signup`, ...), joined to this request's\n * event. Never throws; a silent no-op where the wrapper did not run. See @camada/core/fetch. */\nexport const track = (req: Request, event: string, data?: { user?: string }): Promise<void> => coreTrack(slots.get(req), event, data);\n\n/** The `<script>` tag for an HTML response; `''` where the wrapper did not run or the beacon is off. */\nexport const scriptTag = (req: Request): string => coreScriptTag(slots.get(req));\n\n/** Test/reset hook: stops every poller and queue this module created and drops their engines; the wrappers stay wired and rebuild lazily. */\nexport function resetCamada(): void {\n for (const cam of instances) cam.reset();\n}\n","{\n \"name\": \"@camada/deno\",\n \"version\": \"0.1.3\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=20\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"check\": \"tsc --noEmit\"\n },\n \"description\": \"camada SDK for Deno.serve: snapshot enforcement, first-party challenge and beacon, track() outcomes, timer-polled snapshot and batched event shipping\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"dependencies\": {\n \"@camada/core\": \"file:../camada-core\",\n \"@camada/browser\": \"file:../camada-browser\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.10.0\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.7.2\",\n \"vitest\": \"^3.0.0\"\n }\n}\n","// The SDK's wire identity (SDK-03): x-camada-sdk: <package>/<version>. Named JSON imports are\n// inlined and tree-shaken by tsup at build, so dist carries two literals — no runtime fs read.\nimport { name, version } from '../package.json';\nexport const SDK_ID = `${name}/${version}`;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACOA,yBAAiB;AACjB,kBAAyC;AACzC,mBAA4J;;;ACR1J,WAAQ;AACR,cAAW;;;ACCN,IAAM,SAAS,GAAG,IAAI,IAAI,OAAO;;;AFuBxC,IAAM,YAAY,oBAAI,IAAiB;AAGvC,IAAM,QAAQ,oBAAI,QAA4B;AAI9C,IAAM,WAAW,CAAC,cAAc,gBAAgB,yBAAyB,qBAAqB,uBAAuB,wBAAwB,oBAAoB,mBAAmB,mBAAmB;AAIvM,SAAS,UAA2B;AAClC,QAAM,OAAQ,WAAqC;AACnD,MAAI,CAAC,KAAM,QAAO,WAAW,SAAS;AACtC,QAAM,MAAW,CAAC;AAClB,MAAI,SAAS;AACb,aAAW,KAAK,UAAU;AACxB,QAAI;AAAE,UAAI,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC;AAAA,IAAG,QAAQ;AAAE;AAAA,IAAU;AAAA,EACtD;AACA,MAAI,WAAW,SAAS,OAAQ,iCAAe,IAAI,MAAM,0IAAqI,CAAC;AAC/L,SAAO;AACT;AAGA,IAAM,SAAS,CAAC,SACd,MAAM,YAAY,cAAc,QAAQ,KAAK,WAAW,YAAY,OAAO;AAStE,SAAS,OAAO,OAA0B,CAAC,GAA8C;AAC9F,QAAM,UAAM,gCAAkB,EAAE,KAAK,sBAAU,KAAK,QAAQ,yBAAAA,QAAK,GAAG,EAAE,GAAG,MAAM,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAC3G,YAAU,IAAI,GAAG;AACjB,SAAO,CAAC,YAAY,OAAO,KAAK,SAAS;AACvC,UAAM,IAAI,MAAM,IAAI,OAAO,KAAK,EAAE,MAAM,OAAO,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;AACtE,QAAI,CAAC,EAAG,QAAO,QAAQ,KAAK,IAAI;AAChC,QAAI,EAAE,SAAU,QAAO,EAAE;AACzB,UAAM,IAAI,KAAK,EAAE,IAAI;AACrB,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,QAAQ,KAAK,IAAI;AAAA,IAC/B,SAAS,KAAK;AACZ,UAAI,MAAM,KAAK,EAAE,MAAM,GAAG;AAC1B,YAAM;AAAA,IACR;AAGA,QAAI,IAAI,WAAW,KAAK;AACtB,UAAI,MAAM,KAAK,EAAE,MAAM,GAAG;AAC1B,aAAO;AAAA,IACT;AACA,WAAO,IAAI,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,oBAAgB,4BAAc,KAAK,EAAE,KAAK,aAAa,IAAI,GAAG;AAAA,EACtG;AACF;AAIO,IAAM,QAAQ,CAAC,KAAc,OAAe,aAA4C,aAAAC,OAAU,MAAM,IAAI,GAAG,GAAG,OAAO,IAAI;AAG7H,IAAM,YAAY,CAAC,YAAyB,aAAAC,WAAc,MAAM,IAAI,GAAG,CAAC;AAGxE,SAAS,cAAoB;AAClC,aAAW,OAAO,UAAW,KAAI,MAAM;AACzC;","names":["iife","coreTrack","coreScriptTag"]}
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { createFetchCamada, withSetCookie, track as coreTrack, scriptTag as core
5
5
 
6
6
  // package.json
7
7
  var name = "@camada/deno";
8
- var version = "0.1.1";
8
+ var version = "0.1.3";
9
9
 
10
10
  // src/version.ts
11
11
  var SDK_ID = `${name}/${version}`;
@@ -45,8 +45,11 @@ function camada(opts = {}) {
45
45
  cam.after(req, r.vars, 500);
46
46
  throw err;
47
47
  }
48
- cam.after(req, r.vars, res.status);
49
- return r.vars.sessionCookie ? withSetCookie(res, r.vars.sessionCookie) : res;
48
+ if (res.status === 101) {
49
+ cam.after(req, r.vars, 101);
50
+ return res;
51
+ }
52
+ return cam.finish(req, r.vars, r.vars.sessionCookie ? withSetCookie(res, r.vars.sessionCookie) : res);
50
53
  };
51
54
  }
52
55
  var track = (req, event, data) => coreTrack(slots.get(req), event, data);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/camada.ts","../package.json","../src/version.ts"],"sourcesContent":["// @camada/deno — the Deno.serve wrapper over @camada/core/fetch (SDK-G04).\n// Deno.serve(camada()(handler));\n// The runtime vouches for exactly one thing here: `info.remoteAddr`, the TCP socket peer. It goes\n// in as `ctx.peer` and core combines it with X-Forwarded-For under the trusted-proxy rules; a\n// client header on its own never becomes the ip. Deno is a long-lived process, so the snapshot\n// polls on a timer by default (CAMADA_SERVERLESS=1 or `mode: 'lazy'` for Deno Deploy), and there\n// is no `waitUntil`: the event flush is a fire-and-forget promise the process keeps alive.\nimport iife from '@camada/browser/iife-string';\nimport { TAP_DENO, logRateLimited } from '@camada/core';\nimport { createFetchCamada, withSetCookie, track as coreTrack, scriptTag as coreScriptTag, type FetchCamada, type FetchCamadaOptions, type FetchVars } from '@camada/core/fetch';\nimport { SDK_ID } from './version.js';\n\nexport type CamadaDenoOptions = FetchCamadaOptions;\nexport type CamadaDenoVars = FetchVars;\n\n/** The second argument Deno.serve hands a handler, typed structurally so this package needs no Deno types. */\nexport interface ServeHandlerInfo {\n remoteAddr: { transport: 'tcp' | 'udp' | 'unix' | 'unixpacket'; hostname?: string; port?: number };\n}\nexport type ServeHandler = (req: Request, info: ServeHandlerInfo) => Response | Promise<Response>;\nexport type WrappedHandler = (req: Request, info: ServeHandlerInfo) => Promise<Response>;\n\ntype DenoGlobal = { env: { get(name: string): string | undefined } };\ntype Env = Record<string, string | undefined>;\n\n// Every camada() call owns one pipeline; resetCamada() must reach all of them.\nconst instances = new Set<FetchCamada>();\n// The per-request slot: Deno hands the same Request object to the handler, so track() and\n// scriptTag() find their vars by it without the app threading anything through.\nconst slots = new WeakMap<Request, FetchVars>();\n\n/** Every key core reads, fetched one by one: `Deno.env.get` works under a granular\n * `--allow-env=CAMADA_KEY,…` grant, where `toObject()` (and enumerating `process.env`) throws. */\nconst ENV_KEYS = ['CAMADA_KEY', 'CAMADA_TOKEN', 'CAMADA_SNAPSHOT_TOKEN', 'CAMADA_INGEST_URL', 'CAMADA_SNAPSHOT_URL', 'CAMADA_TRUSTED_PROXY', 'CAMADA_CHALLENGE', 'CAMADA_DISABLED', 'CAMADA_SERVERLESS'];\n\n/** Deno.env where there is a Deno (a Node test process has only process.env). A key the grant does\n * not cover throws NotCapable; that costs enforcement, never the response, and is logged as what it is. */\nfunction hostEnv(): Env | undefined {\n const deno = (globalThis as { Deno?: DenoGlobal }).Deno;\n if (!deno) return globalThis.process?.env;\n const env: Env = {};\n let denied = 0;\n for (const k of ENV_KEYS) {\n try { env[k] = deno.env.get(k); } catch { denied++; }\n }\n if (denied === ENV_KEYS.length) logRateLimited(new Error('Deno.env access denied — run with --allow-env (or --allow-env=CAMADA_KEY,CAMADA_INGEST_URL,CAMADA_SNAPSHOT_URL); camada is inactive'));\n return env;\n}\n\n/** Only a TCP peer is an address; a unix socket has none, and camada then sees no client ip. */\nconst peerOf = (info: ServeHandlerInfo | undefined): string | null =>\n info?.remoteAddr?.transport === 'tcp' ? info.remoteAddr.hostname ?? null : null;\n\n/**\n * Builds the wrapper: `Deno.serve(camada()(handler))`. Mode defaults to `timer` (a long-lived\n * process polls the snapshot on an unref'd interval); `opts.mode` overrides and CAMADA_SERVERLESS=1\n * forces lazy. Deno's setInterval returns a number, so that unref is a no-op there and the poll\n * keeps the process alive until resetCamada() or exit — under Node (vitest) resetCamada() is what\n * lets a test process end.\n */\nexport function camada(opts: CamadaDenoOptions = {}): (handler: ServeHandler) => WrappedHandler {\n const cam = createFetchCamada({ tap: TAP_DENO, sdk: SDK_ID, iife }, { ...opts, mode: opts.mode ?? 'timer' });\n instances.add(cam);\n return (handler) => async (req, info) => {\n const r = await cam.before(req, { peer: peerOf(info), env: hostEnv() });\n if (!r) return handler(req, info);\n if (r.response) return r.response;\n slots.set(req, r.vars);\n let res: Response;\n try {\n res = await handler(req, info);\n } catch (err) {\n cam.after(req, r.vars, 500); // Deno.serve answers 500 for a thrown handler (an onError returning its own status is not visible here)\n throw err;\n }\n cam.after(req, r.vars, res.status);\n return r.vars.sessionCookie ? withSetCookie(res, r.vars.sessionCookie) : res;\n };\n}\n\n/** Records an outcome the handler knows (`login_failed`, `signup`, ...), joined to this request's\n * event. Never throws; a silent no-op where the wrapper did not run. See @camada/core/fetch. */\nexport const track = (req: Request, event: string, data?: { user?: string }): Promise<void> => coreTrack(slots.get(req), event, data);\n\n/** The `<script>` tag for an HTML response; `''` where the wrapper did not run or the beacon is off. */\nexport const scriptTag = (req: Request): string => coreScriptTag(slots.get(req));\n\n/** Test/reset hook: stops every poller and queue this module created and drops their engines; the wrappers stay wired and rebuild lazily. */\nexport function resetCamada(): void {\n for (const cam of instances) cam.reset();\n}\n","{\n \"name\": \"@camada/deno\",\n \"version\": \"0.1.1\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=20\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"check\": \"tsc --noEmit\"\n },\n \"description\": \"camada SDK for Deno.serve: snapshot enforcement, first-party challenge and beacon, track() outcomes, timer-polled snapshot and batched event shipping\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"dependencies\": {\n \"@camada/core\": \"file:../camada-core\",\n \"@camada/browser\": \"file:../camada-browser\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.10.0\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.7.2\",\n \"vitest\": \"^3.0.0\"\n }\n}\n","// The SDK's wire identity (SDK-03): x-camada-sdk: <package>/<version>. Named JSON imports are\n// inlined and tree-shaken by tsup at build, so dist carries two literals — no runtime fs read.\nimport { name, version } from '../package.json';\nexport const SDK_ID = `${name}/${version}`;\n"],"mappings":";AAOA,OAAO,UAAU;AACjB,SAAS,UAAU,sBAAsB;AACzC,SAAS,mBAAmB,eAAe,SAAS,WAAW,aAAa,qBAAgF;;;ACR1J,WAAQ;AACR,cAAW;;;ACCN,IAAM,SAAS,GAAG,IAAI,IAAI,OAAO;;;AFuBxC,IAAM,YAAY,oBAAI,IAAiB;AAGvC,IAAM,QAAQ,oBAAI,QAA4B;AAI9C,IAAM,WAAW,CAAC,cAAc,gBAAgB,yBAAyB,qBAAqB,uBAAuB,wBAAwB,oBAAoB,mBAAmB,mBAAmB;AAIvM,SAAS,UAA2B;AAClC,QAAM,OAAQ,WAAqC;AACnD,MAAI,CAAC,KAAM,QAAO,WAAW,SAAS;AACtC,QAAM,MAAW,CAAC;AAClB,MAAI,SAAS;AACb,aAAW,KAAK,UAAU;AACxB,QAAI;AAAE,UAAI,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC;AAAA,IAAG,QAAQ;AAAE;AAAA,IAAU;AAAA,EACtD;AACA,MAAI,WAAW,SAAS,OAAQ,gBAAe,IAAI,MAAM,0IAAqI,CAAC;AAC/L,SAAO;AACT;AAGA,IAAM,SAAS,CAAC,SACd,MAAM,YAAY,cAAc,QAAQ,KAAK,WAAW,YAAY,OAAO;AAStE,SAAS,OAAO,OAA0B,CAAC,GAA8C;AAC9F,QAAM,MAAM,kBAAkB,EAAE,KAAK,UAAU,KAAK,QAAQ,KAAK,GAAG,EAAE,GAAG,MAAM,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAC3G,YAAU,IAAI,GAAG;AACjB,SAAO,CAAC,YAAY,OAAO,KAAK,SAAS;AACvC,UAAM,IAAI,MAAM,IAAI,OAAO,KAAK,EAAE,MAAM,OAAO,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;AACtE,QAAI,CAAC,EAAG,QAAO,QAAQ,KAAK,IAAI;AAChC,QAAI,EAAE,SAAU,QAAO,EAAE;AACzB,UAAM,IAAI,KAAK,EAAE,IAAI;AACrB,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,QAAQ,KAAK,IAAI;AAAA,IAC/B,SAAS,KAAK;AACZ,UAAI,MAAM,KAAK,EAAE,MAAM,GAAG;AAC1B,YAAM;AAAA,IACR;AACA,QAAI,MAAM,KAAK,EAAE,MAAM,IAAI,MAAM;AACjC,WAAO,EAAE,KAAK,gBAAgB,cAAc,KAAK,EAAE,KAAK,aAAa,IAAI;AAAA,EAC3E;AACF;AAIO,IAAM,QAAQ,CAAC,KAAc,OAAe,SAA4C,UAAU,MAAM,IAAI,GAAG,GAAG,OAAO,IAAI;AAG7H,IAAM,YAAY,CAAC,QAAyB,cAAc,MAAM,IAAI,GAAG,CAAC;AAGxE,SAAS,cAAoB;AAClC,aAAW,OAAO,UAAW,KAAI,MAAM;AACzC;","names":[]}
1
+ {"version":3,"sources":["../src/camada.ts","../package.json","../src/version.ts"],"sourcesContent":["// @camada/deno — the Deno.serve wrapper over @camada/core/fetch (SDK-G04).\n// Deno.serve(camada()(handler));\n// The runtime vouches for exactly one thing here: `info.remoteAddr`, the TCP socket peer. It goes\n// in as `ctx.peer` and core combines it with X-Forwarded-For under the trusted-proxy rules; a\n// client header on its own never becomes the ip. Deno is a long-lived process, so the snapshot\n// polls on a timer by default (CAMADA_SERVERLESS=1 or `mode: 'lazy'` for Deno Deploy), and there\n// is no `waitUntil`: the event flush is a fire-and-forget promise the process keeps alive.\nimport iife from '@camada/browser/iife-string';\nimport { TAP_DENO, logRateLimited } from '@camada/core';\nimport { createFetchCamada, withSetCookie, track as coreTrack, scriptTag as coreScriptTag, type FetchCamada, type FetchCamadaOptions, type FetchVars } from '@camada/core/fetch';\nimport { SDK_ID } from './version.js';\n\nexport type CamadaDenoOptions = FetchCamadaOptions;\nexport type CamadaDenoVars = FetchVars;\n\n/** The second argument Deno.serve hands a handler, typed structurally so this package needs no Deno types. */\nexport interface ServeHandlerInfo {\n remoteAddr: { transport: 'tcp' | 'udp' | 'unix' | 'unixpacket'; hostname?: string; port?: number };\n}\nexport type ServeHandler = (req: Request, info: ServeHandlerInfo) => Response | Promise<Response>;\nexport type WrappedHandler = (req: Request, info: ServeHandlerInfo) => Promise<Response>;\n\ntype DenoGlobal = { env: { get(name: string): string | undefined } };\ntype Env = Record<string, string | undefined>;\n\n// Every camada() call owns one pipeline; resetCamada() must reach all of them.\nconst instances = new Set<FetchCamada>();\n// The per-request slot: Deno hands the same Request object to the handler, so track() and\n// scriptTag() find their vars by it without the app threading anything through.\nconst slots = new WeakMap<Request, FetchVars>();\n\n/** Every key core reads, fetched one by one: `Deno.env.get` works under a granular\n * `--allow-env=CAMADA_KEY,…` grant, where `toObject()` (and enumerating `process.env`) throws. */\nconst ENV_KEYS = ['CAMADA_KEY', 'CAMADA_TOKEN', 'CAMADA_SNAPSHOT_TOKEN', 'CAMADA_INGEST_URL', 'CAMADA_SNAPSHOT_URL', 'CAMADA_TRUSTED_PROXY', 'CAMADA_CHALLENGE', 'CAMADA_DISABLED', 'CAMADA_SERVERLESS'];\n\n/** Deno.env where there is a Deno (a Node test process has only process.env). A key the grant does\n * not cover throws NotCapable; that costs enforcement, never the response, and is logged as what it is. */\nfunction hostEnv(): Env | undefined {\n const deno = (globalThis as { Deno?: DenoGlobal }).Deno;\n if (!deno) return globalThis.process?.env;\n const env: Env = {};\n let denied = 0;\n for (const k of ENV_KEYS) {\n try { env[k] = deno.env.get(k); } catch { denied++; }\n }\n if (denied === ENV_KEYS.length) logRateLimited(new Error('Deno.env access denied — run with --allow-env (or --allow-env=CAMADA_KEY,CAMADA_INGEST_URL,CAMADA_SNAPSHOT_URL); camada is inactive'));\n return env;\n}\n\n/** Only a TCP peer is an address; a unix socket has none, and camada then sees no client ip. */\nconst peerOf = (info: ServeHandlerInfo | undefined): string | null =>\n info?.remoteAddr?.transport === 'tcp' ? info.remoteAddr.hostname ?? null : null;\n\n/**\n * Builds the wrapper: `Deno.serve(camada()(handler))`. Mode defaults to `timer` (a long-lived\n * process polls the snapshot on an unref'd interval); `opts.mode` overrides and CAMADA_SERVERLESS=1\n * forces lazy. Deno's setInterval returns a number, so that unref is a no-op there and the poll\n * keeps the process alive until resetCamada() or exit — under Node (vitest) resetCamada() is what\n * lets a test process end.\n */\nexport function camada(opts: CamadaDenoOptions = {}): (handler: ServeHandler) => WrappedHandler {\n const cam = createFetchCamada({ tap: TAP_DENO, sdk: SDK_ID, iife }, { ...opts, mode: opts.mode ?? 'timer' });\n instances.add(cam);\n return (handler) => async (req, info) => {\n const r = await cam.before(req, { peer: peerOf(info), env: hostEnv() });\n if (!r) return handler(req, info);\n if (r.response) return r.response;\n slots.set(req, r.vars);\n let res: Response;\n try {\n res = await handler(req, info);\n } catch (err) {\n cam.after(req, r.vars, 500); // Deno.serve answers 500 for a thrown handler (an onError returning its own status is not visible here)\n throw err;\n }\n // A WebSocket upgrade must go back as the very Response Deno.upgradeWebSocket made: Deno < 2.6 stops\n // Deno.serve over a copy, and its headers are immutable, so it gets no session cookie. It has no body to time.\n if (res.status === 101) {\n cam.after(req, r.vars, 101);\n return res;\n }\n return cam.finish(req, r.vars, r.vars.sessionCookie ? withSetCookie(res, r.vars.sessionCookie) : res); // ships once the body has gone out\n };\n}\n\n/** Records an outcome the handler knows (`login_failed`, `signup`, ...), joined to this request's\n * event. Never throws; a silent no-op where the wrapper did not run. See @camada/core/fetch. */\nexport const track = (req: Request, event: string, data?: { user?: string }): Promise<void> => coreTrack(slots.get(req), event, data);\n\n/** The `<script>` tag for an HTML response; `''` where the wrapper did not run or the beacon is off. */\nexport const scriptTag = (req: Request): string => coreScriptTag(slots.get(req));\n\n/** Test/reset hook: stops every poller and queue this module created and drops their engines; the wrappers stay wired and rebuild lazily. */\nexport function resetCamada(): void {\n for (const cam of instances) cam.reset();\n}\n","{\n \"name\": \"@camada/deno\",\n \"version\": \"0.1.3\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=20\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"check\": \"tsc --noEmit\"\n },\n \"description\": \"camada SDK for Deno.serve: snapshot enforcement, first-party challenge and beacon, track() outcomes, timer-polled snapshot and batched event shipping\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"dependencies\": {\n \"@camada/core\": \"file:../camada-core\",\n \"@camada/browser\": \"file:../camada-browser\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.10.0\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.7.2\",\n \"vitest\": \"^3.0.0\"\n }\n}\n","// The SDK's wire identity (SDK-03): x-camada-sdk: <package>/<version>. Named JSON imports are\n// inlined and tree-shaken by tsup at build, so dist carries two literals — no runtime fs read.\nimport { name, version } from '../package.json';\nexport const SDK_ID = `${name}/${version}`;\n"],"mappings":";AAOA,OAAO,UAAU;AACjB,SAAS,UAAU,sBAAsB;AACzC,SAAS,mBAAmB,eAAe,SAAS,WAAW,aAAa,qBAAgF;;;ACR1J,WAAQ;AACR,cAAW;;;ACCN,IAAM,SAAS,GAAG,IAAI,IAAI,OAAO;;;AFuBxC,IAAM,YAAY,oBAAI,IAAiB;AAGvC,IAAM,QAAQ,oBAAI,QAA4B;AAI9C,IAAM,WAAW,CAAC,cAAc,gBAAgB,yBAAyB,qBAAqB,uBAAuB,wBAAwB,oBAAoB,mBAAmB,mBAAmB;AAIvM,SAAS,UAA2B;AAClC,QAAM,OAAQ,WAAqC;AACnD,MAAI,CAAC,KAAM,QAAO,WAAW,SAAS;AACtC,QAAM,MAAW,CAAC;AAClB,MAAI,SAAS;AACb,aAAW,KAAK,UAAU;AACxB,QAAI;AAAE,UAAI,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC;AAAA,IAAG,QAAQ;AAAE;AAAA,IAAU;AAAA,EACtD;AACA,MAAI,WAAW,SAAS,OAAQ,gBAAe,IAAI,MAAM,0IAAqI,CAAC;AAC/L,SAAO;AACT;AAGA,IAAM,SAAS,CAAC,SACd,MAAM,YAAY,cAAc,QAAQ,KAAK,WAAW,YAAY,OAAO;AAStE,SAAS,OAAO,OAA0B,CAAC,GAA8C;AAC9F,QAAM,MAAM,kBAAkB,EAAE,KAAK,UAAU,KAAK,QAAQ,KAAK,GAAG,EAAE,GAAG,MAAM,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAC3G,YAAU,IAAI,GAAG;AACjB,SAAO,CAAC,YAAY,OAAO,KAAK,SAAS;AACvC,UAAM,IAAI,MAAM,IAAI,OAAO,KAAK,EAAE,MAAM,OAAO,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;AACtE,QAAI,CAAC,EAAG,QAAO,QAAQ,KAAK,IAAI;AAChC,QAAI,EAAE,SAAU,QAAO,EAAE;AACzB,UAAM,IAAI,KAAK,EAAE,IAAI;AACrB,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,QAAQ,KAAK,IAAI;AAAA,IAC/B,SAAS,KAAK;AACZ,UAAI,MAAM,KAAK,EAAE,MAAM,GAAG;AAC1B,YAAM;AAAA,IACR;AAGA,QAAI,IAAI,WAAW,KAAK;AACtB,UAAI,MAAM,KAAK,EAAE,MAAM,GAAG;AAC1B,aAAO;AAAA,IACT;AACA,WAAO,IAAI,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,gBAAgB,cAAc,KAAK,EAAE,KAAK,aAAa,IAAI,GAAG;AAAA,EACtG;AACF;AAIO,IAAM,QAAQ,CAAC,KAAc,OAAe,SAA4C,UAAU,MAAM,IAAI,GAAG,GAAG,OAAO,IAAI;AAG7H,IAAM,YAAY,CAAC,QAAyB,cAAc,MAAM,IAAI,GAAG,CAAC;AAGxE,SAAS,cAAoB;AAClC,aAAW,OAAO,UAAW,KAAI,MAAM;AACzC;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camada/deno",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "engines": {
@@ -23,8 +23,8 @@
23
23
  "module": "./dist/index.js",
24
24
  "types": "./dist/index.d.ts",
25
25
  "dependencies": {
26
- "@camada/core": "^0.4.0",
27
- "@camada/browser": "^0.2.0"
26
+ "@camada/core": "^0.5.1",
27
+ "@camada/browser": "^0.3.0"
28
28
  },
29
29
  "repository": {
30
30
  "type": "git",