@lunora/container 1.0.0-alpha.35 → 1.0.0-alpha.36

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
@@ -196,7 +196,7 @@ await lunora.mutation("jobs:markDone", { id: pending[0].id });
196
196
 
197
197
  The token is a bearer your Worker's `resolveIdentity` recognizes — pass it to the container as a `secret`. Non-JS containers can `POST /_lunora/rpc` with `{ functionPath, args }` directly.
198
198
 
199
- Secure the bridge in `resolveIdentity`: read `request.headers.get("authorization")`, strip the `Bearer ` prefix, and compare the token against a Worker secret (e.g. `env.LUNORA_CONTAINER_TOKEN`) you also forward to the container. Return a `{ userId }` identity only on a match and `null` otherwise — an unrecognised request then runs anonymously and is rejected by your functions' own authorization checks. See [Securing the bridge](https://lunora.sh/docs/addons/containers#securing-the-bridge) for the full example.
199
+ Secure the bridge in `resolveIdentity`: read `request.headers.get("authorization")`, strip the `Bearer ` prefix, and compare the token against a Worker secret (e.g. `env.LUNORA_CONTAINER_TOKEN`) you also forward to the container. Return a `{ userId }` identity only on a match and `null` otherwise — an unrecognised request then runs anonymously and is rejected by your functions' own authorization checks. See [Securing the bridge](https://lunora.sh/docs/packages/container#securing-the-bridge) for the full example.
200
200
 
201
201
  ### Entry points
202
202
 
@@ -204,7 +204,7 @@ Secure the bridge in `resolveIdentity`: read `request.headers.get("authorization
204
204
  - `@lunora/container/do` — workerd-only: the `LunoraContainer` base class the generated DO classes extend (pulls in `@cloudflare/containers`).
205
205
  - `@lunora/container/bridge` — runtime-agnostic: `createContainerBridge` for calling Lunora functions from inside a container.
206
206
 
207
- > This README covers the basics. For the full API, options, and guides, see the **[documentation](https://lunora.sh/docs/addons/containers)**.
207
+ > This README covers the basics. For the full API, options, and guides, see the **[documentation](https://lunora.sh/docs/packages/container)**.
208
208
 
209
209
  ### Known platform limitations
210
210
 
package/dist/otel.mjs CHANGED
@@ -1 +1 @@
1
- import{a as U}from"./packem_shared/abort-deadline-jwbW9Ala.mjs";const x={debug:5,error:17,fatal:21,info:9,log:9,trace:1,warn:13},N=e=>`${String(Math.round(e))}000000`,R=e=>{const t=new Uint8Array(e);crypto.getRandomValues(t);let r="";for(const n of t)r+=n.toString(16).padStart(2,"0");return r},b=/^[0-9a-f]+$/,C=e=>{if(e==null)return;const t=e.trim().toLowerCase().split("-"),[r,n,o,s]=t;if(!(t.length<4||r===void 0||r.length!==2||!b.test(r)||r==="ff"||r==="00"&&t.length!==4||n===void 0||o===void 0||s===void 0||s.length!==2||!b.test(s)||n.length!==32||o.length!==16||!b.test(n)||!b.test(o)||n==="00000000000000000000000000000000"||o==="0000000000000000"))return{parentSpanId:o,sampled:(Number.parseInt(s,16)&1)===1,traceId:n}},v=(e,t)=>typeof t=="boolean"?{key:e,value:{boolValue:t}}:typeof t=="number"?Number.isFinite(t)?Number.isSafeInteger(t)?{key:e,value:{intValue:String(t)}}:{key:e,value:{doubleValue:t}}:{key:e,value:{stringValue:String(t)}}:{key:e,value:{stringValue:t}},M=e=>e===void 0?[]:Object.entries(e).map(([t,r])=>v(t,r)),D=(e,t,r)=>{const n={},o=new Map,s=(c,d)=>{const p=c.toLowerCase(),E=o.get(p);E===void 0?(o.set(p,c),n[c]=d):n[E]=d};for(const[c,d]of Object.entries(e))s(c,d);for(const[c,d]of Object.entries(t??{}))s(c,d);return r!==void 0&&r.length>0&&s("authorization",`Bearer ${r}`),n},_=e=>Array.isArray(e)?e:[e],I=(e,t)=>{const r={"service.name":e};for(const[n,o]of Object.entries(t??{}))r[n]=o;return Object.entries(r).map(([n,o])=>v(n,o))},P=(e,t,r,n)=>({resourceSpans:[{resource:{attributes:I(r,n)},scopeSpans:[{scope:{name:t},spans:_(e)}]}]}),H=(e,t,r,n)=>({resourceLogs:[{resource:{attributes:I(r,n)},scopeLogs:[{logRecords:_(e),scope:{name:t}}]}]}),$=e=>{const t={},r=e("SERVICE_VERSION")??e("CF_VERSION_METADATA")??e("VERCEL_GIT_COMMIT_SHA")??e("GITHUB_SHA")??e("COMMIT_SHA");r!==void 0&&(t["service.version"]=r);const n=e("DEPLOYMENT_ENVIRONMENT")??e("ENVIRONMENT")??e("NODE_ENV");return n!==void 0&&(t["deployment.environment"]=n),t},j=(e,t)=>{const r={},n=e("HOSTNAME")??e("COMPUTERNAME");n!==void 0&&(r["host.name"]=n);const o=e("KUBERNETES_POD_NAME")??e("HOSTNAME");return o!==void 0&&e("KUBERNETES_SERVICE_HOST")!==void 0&&(r["k8s.pod.name"]=o),t!==void 0&&Number.isFinite(t)&&(r["process.pid"]=t),r},w=(...e)=>{const t={};for(const r of e)if(r!==void 0)for(const[n,o]of Object.entries(r))t[n]=o;return t},B=1e4,u=e=>process.env[e],F=()=>{const e=typeof process.pid!="number"?void 0:process.pid;return w($(u),j(u,e))},K=e=>e??(typeof globalThis.fetch=="function"?globalThis.fetch:void 0),Y=(e,t,r,n)=>{const o=M(e.attributes);e.error?.type!==void 0&&o.push(v("error.type",e.error.type));const s={attributes:o,endTimeUnixNano:N(e.endMs),kind:1,name:e.name,...r===void 0?{}:{parentSpanId:r.parentSpanId},spanId:R(8),startTimeUnixNano:N(e.startMs),status:e.error===void 0?{code:1}:{code:2,message:e.error.message},traceId:r?.traceId??R(16)};return e.error&&(s.events=[{attributes:[v("exception.type",e.error.type??"Error"),v("exception.message",e.error.message)],name:"exception",timeUnixNano:N(e.endMs)}]),P(s,"@lunora/container",t,n)},G=(e,t,r,n)=>{const o=e.level??"info",s={attributes:M(e.attributes),body:{stringValue:e.message},severityNumber:x[o],severityText:o.toUpperCase(),timeUnixNano:N(e.ts??r)};return H(s,"@lunora/container",t,n)},X=(e={})=>{const t=e.endpoint??u("LUNORA_OTLP_ENDPOINT"),r=t!==void 0&&t.length>0,n=e.token??u("LUNORA_OTLP_TOKEN"),o=e.serviceName??u("LUNORA_SERVICE_NAME")??"lunora-container",s=C(e.traceparent??u("LUNORA_TRACEPARENT")),c=e.timeoutMs??B,d=K(e.fetch),p=D({"content-type":"application/json"},e.headers,n),E=e.detectResources===!0?F():void 0,g={};e.serviceVersion!==void 0&&(g["service.version"]=e.serviceVersion),e.deploymentEnvironment!==void 0&&(g["deployment.environment"]=e.deploymentEnvironment),e.resourceAttributes!==void 0&&Object.assign(g,e.resourceAttributes);const O=w(E,g);let l=t??"";for(;l.endsWith("/");)l=l.slice(0,-1);const L=`${l}/v1/traces`,V=`${l}/v1/logs`,y=new Set,A=(a,h)=>{if(d===void 0){e.onError?.(new TypeError("createContainerTelemetry: no `fetch` available — pass `fetch` in options for this runtime."));return}const f=(async()=>{const i=U(void 0,c,()=>new DOMException(`OTLP export to ${a} timed out after ${String(c)}ms`,"TimeoutError"));try{const m=await d(a,{body:JSON.stringify(h),headers:p,method:"POST",signal:i.signal});m.ok||e.onError?.(new Error(`createContainerTelemetry: OTLP export to ${a} failed with status ${String(m.status)}.`));try{await m.body?.cancel()}catch{}}catch(m){e.onError?.(m)}finally{i.dispose()}})().finally(()=>{y.delete(f)});y.add(f)},T=a=>{r&&A(L,Y(a,o,s,O))};return{emitLog:a=>{r&&A(V,G(a,o,Date.now(),O))},emitSpan:T,enabled:r,flush:async()=>{await Promise.allSettled(y)},trace:async(a,h,S)=>{const f=Date.now();try{const i=await h();return T({attributes:S,endMs:Date.now(),name:a,startMs:f}),i}catch(i){throw T({attributes:S,endMs:Date.now(),error:{message:i instanceof Error?i.message:String(i),type:i instanceof Error?i.name:void 0},name:a,startMs:f}),i}}}};export{X as createContainerTelemetry};
1
+ import{a as D}from"./packem_shared/abort-deadline-jwbW9Ala.mjs";const H={debug:5,error:17,fatal:21,info:9,log:9,trace:1,warn:13},h=e=>`${String(Math.round(e))}000000`,$=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0")),O=512,M=new Uint8Array(O);let N=O;const w=(e,t,r)=>{let n="";for(let o=0;o<r;o+=1)n+=$[e[t+o]];return n},I=e=>{if(e>O){const r=new Uint8Array(e);return crypto.getRandomValues(r),w(r,0,e)}N+e>O&&(crypto.getRandomValues(M),N=0);const t=w(M,N,e);return N+=e,t},T=/^[0-9a-f]+$/,j=e=>{if(e==null)return;const t=e.trim().toLowerCase().split("-"),[r,n,o,s]=t;if(!(t.length<4||r===void 0||r.length!==2||!T.test(r)||r==="ff"||r==="00"&&t.length!==4||n===void 0||o===void 0||s===void 0||s.length!==2||!T.test(s)||n.length!==32||o.length!==16||!T.test(n)||!T.test(o)||n==="00000000000000000000000000000000"||o==="0000000000000000"))return{parentSpanId:o,sampled:(Number.parseInt(s,16)&1)===1,traceId:n}},v=(e,t)=>typeof t=="boolean"?{key:e,value:{boolValue:t}}:typeof t=="number"?Number.isFinite(t)?Number.isSafeInteger(t)?{key:e,value:{intValue:String(t)}}:{key:e,value:{doubleValue:t}}:{key:e,value:{stringValue:String(t)}}:{key:e,value:{stringValue:t}},L=e=>e===void 0?[]:Object.entries(e).map(([t,r])=>v(t,r)),B=(e,t,r)=>{const n={},o=new Map,s=(c,d)=>{const E=c.toLowerCase(),p=o.get(E);p===void 0?(o.set(E,c),n[c]=d):n[p]=d};for(const[c,d]of Object.entries(e))s(c,d);for(const[c,d]of Object.entries(t??{}))s(c,d);return r!==void 0&&r.length>0&&s("authorization",`Bearer ${r}`),n},V=e=>Array.isArray(e)?e:[e],U=(e,t)=>{const r={"service.name":e};for(const[n,o]of Object.entries(t??{}))r[n]=o;return Object.entries(r).map(([n,o])=>v(n,o))},F=(e,t,r,n)=>({resourceSpans:[{resource:{attributes:U(r,n)},scopeSpans:[{scope:{name:t},spans:V(e)}]}]}),Y=(e,t,r,n)=>({resourceLogs:[{resource:{attributes:U(r,n)},scopeLogs:[{logRecords:V(e),scope:{name:t}}]}]}),K=e=>{const t={},r=e("SERVICE_VERSION")??e("CF_VERSION_METADATA")??e("VERCEL_GIT_COMMIT_SHA")??e("GITHUB_SHA")??e("COMMIT_SHA");r!==void 0&&(t["service.version"]=r);const n=e("DEPLOYMENT_ENVIRONMENT")??e("ENVIRONMENT")??e("NODE_ENV");return n!==void 0&&(t["deployment.environment"]=n),t},G=(e,t)=>{const r={},n=e("HOSTNAME")??e("COMPUTERNAME");n!==void 0&&(r["host.name"]=n);const o=e("KUBERNETES_POD_NAME")??e("HOSTNAME");return o!==void 0&&e("KUBERNETES_SERVICE_HOST")!==void 0&&(r["k8s.pod.name"]=o),t!==void 0&&Number.isFinite(t)&&(r["process.pid"]=t),r},x=(...e)=>{const t={};for(const r of e)if(r!==void 0)for(const[n,o]of Object.entries(r))t[n]=o;return t},X=1e4,u=e=>process.env[e],k=()=>{const e=typeof process.pid!="number"?void 0:process.pid;return x(K(u),G(u,e))},z=e=>e??(typeof globalThis.fetch=="function"?globalThis.fetch:void 0),J=(e,t,r,n)=>{const o=L(e.attributes);e.error?.type!==void 0&&o.push(v("error.type",e.error.type));const s={attributes:o,endTimeUnixNano:h(e.endMs),kind:1,name:e.name,...r===void 0?{}:{parentSpanId:r.parentSpanId},spanId:I(8),startTimeUnixNano:h(e.startMs),status:e.error===void 0?{code:1}:{code:2,message:e.error.message},traceId:r?.traceId??I(16)};return e.error&&(s.events=[{attributes:[v("exception.type",e.error.type??"Error"),v("exception.message",e.error.message)],name:"exception",timeUnixNano:h(e.endMs)}]),F(s,"@lunora/container",t,n)},W=(e,t,r,n)=>{const o=e.level??"info",s={attributes:L(e.attributes),body:{stringValue:e.message},severityNumber:H[o],severityText:o.toUpperCase(),timeUnixNano:h(e.ts??r)};return Y(s,"@lunora/container",t,n)},te=(e={})=>{const t=e.endpoint??u("LUNORA_OTLP_ENDPOINT"),r=t!==void 0&&t.length>0,n=e.token??u("LUNORA_OTLP_TOKEN"),o=e.serviceName??u("LUNORA_SERVICE_NAME")??"lunora-container",s=j(e.traceparent??u("LUNORA_TRACEPARENT")),c=e.timeoutMs??X,d=z(e.fetch),E=B({"content-type":"application/json"},e.headers,n),p=e.detectResources===!0?k():void 0,g={};e.serviceVersion!==void 0&&(g["service.version"]=e.serviceVersion),e.deploymentEnvironment!==void 0&&(g["deployment.environment"]=e.deploymentEnvironment),e.resourceAttributes!==void 0&&Object.assign(g,e.resourceAttributes);const R=x(p,g);let l=t??"";for(;l.endsWith("/");)l=l.slice(0,-1);const C=`${l}/v1/traces`,P=`${l}/v1/logs`,S=new Set,_=(a,y)=>{if(d===void 0){e.onError?.(new TypeError("createContainerTelemetry: no `fetch` available — pass `fetch` in options for this runtime."));return}const f=(async()=>{const i=D(void 0,c,()=>new DOMException(`OTLP export to ${a} timed out after ${String(c)}ms`,"TimeoutError"));try{const m=await d(a,{body:JSON.stringify(y),headers:E,method:"POST",signal:i.signal});m.ok||e.onError?.(new Error(`createContainerTelemetry: OTLP export to ${a} failed with status ${String(m.status)}.`));try{await m.body?.cancel()}catch{}}catch(m){e.onError?.(m)}finally{i.dispose()}})().finally(()=>{S.delete(f)});S.add(f)},b=a=>{r&&_(C,J(a,o,s,R))};return{emitLog:a=>{r&&_(P,W(a,o,Date.now(),R))},emitSpan:b,enabled:r,flush:async()=>{await Promise.allSettled(S)},trace:async(a,y,A)=>{const f=Date.now();try{const i=await y();return b({attributes:A,endMs:Date.now(),name:a,startMs:f}),i}catch(i){throw b({attributes:A,endMs:Date.now(),error:{message:i instanceof Error?i.message:String(i),type:i instanceof Error?i.name:void 0},name:a,startMs:f}),i}}}};export{te as createContainerTelemetry};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/container",
3
- "version": "1.0.0-alpha.35",
3
+ "version": "1.0.0-alpha.36",
4
4
  "description": "Cloudflare Containers for Lunora: defineContainer, generated Container DO classes, and the ctx.containers action surface",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -56,7 +56,7 @@
56
56
  "access": "public"
57
57
  },
58
58
  "dependencies": {
59
- "@lunora/errors": "1.0.0-alpha.24"
59
+ "@lunora/errors": "1.0.0-alpha.25"
60
60
  },
61
61
  "engines": {
62
62
  "node": "^22.15.0 || >=24.11.0"