Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fauna

Package Overview
Dependencies
Maintainers
2
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fauna - npm Package Compare versions

Comparing version 0.7.0 to 0.7.1

2

dist/browser/index.js

@@ -1,2 +0,2 @@

var pe=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+r+'" is not supported')});var oe=(r,e,t)=>{if(!e.has(r))throw TypeError("Cannot "+t)};var g=(r,e,t)=>(oe(r,e,"read from private field"),t?t.call(r):e.get(r)),U=(r,e,t)=>{if(e.has(r))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(r):e.set(r,t)},ae=(r,e,t,n)=>(oe(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t);var W=(r,e,t)=>(oe(r,e,"access private method"),t);var ie={default:new URL("https://db.fauna.com"),local:new URL("http://localhost:8443"),localhost:new URL("http://localhost:8443")};var D=class extends Error{constructor(...e){super(...e)}},a=class extends D{httpStatus;code;queryInfo;constraint_failures;constructor(e,t){super(e.error.message),Error.captureStackTrace&&Error.captureStackTrace(this,a),this.name="ServiceError",this.code=e.error.code,this.httpStatus=t;let n={txn_ts:e.txn_ts,summary:e.summary,query_tags:e.query_tags,stats:e.stats};this.queryInfo=n,this.constraint_failures=e.error.constraint_failures}},I=class extends a{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,I),this.name="QueryRuntimeError"}},Q=class extends a{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,Q),this.name="QueryCheckError"}},E=class extends a{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,E),this.name="InvalidRequestError"}},X=class extends a{abort;constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,Q),this.name="AbortError",this.abort=e.error.abort}},V=class extends a{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,V),this.name="AuthenticationError"}},k=class extends a{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,k),this.name="AuthorizationError"}},Z=class extends a{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,E),this.name="ContendedTransactionError"}},F=class extends a{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,F),this.name="ThrottlingError"}},O=class extends a{stats;constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,O),this.name="QueryTimeoutError",this.stats=e.stats}},N=class extends a{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,N),this.name="ServiceInternalError"}},A=class extends a{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,A),this.name="ServiceTimeoutError"}},y=class extends D{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,y),this.name="ClientError"}},_=class extends D{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,_),this.name="ClientClosedError"}},p=class extends D{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,p),this.name="NetworkError"}},T=class extends D{httpStatus;constructor(e){super(e.message),Error.captureStackTrace&&Error.captureStackTrace(this,T),this.name="ProtocolError",this.httpStatus=e.httpStatus}};var Re=/(?:\d{4}|[\u2212-]\d{4,}|\+\d{5,})/,Pe=/(?:0[1-9]|1[0-2])/,Ce=/(?:0[1-9]|[12]\d|3[01])/,fe=/(?:[01][0-9]|2[0-3])/,ee=/(?:[0-5][0-9])/,He=/(?:\.\d+)/,ce=new RegExp(`(${Re.source}-(${Pe.source})-(${Ce.source}))`),qe=new RegExp(`(${fe.source}:${ee.source}:${ee.source}${He.source}?)`),De=new RegExp(`([zZ]|[+\u2212-]${fe.source}(?::?${ee.source}|:${ee.source}:${ee.source}))`),ge=new RegExp(`^${ce.source}$`),Te=new RegExp(`^${ce.source}`),he=new RegExp(`^${ce.source}T${qe.source}${De.source}$`);var h=class{isoString;constructor(e){this.isoString=e}static from(e){if(typeof e!="string")throw new TypeError(`Expected string but received ${typeof e}: ${e}`);if(he.exec(e)===null)throw new RangeError(`(regex) Expected an ISO date string but received '${e}'`);return new h(e)}static fromDate(e){return new h(e.toISOString())}toDate(){let e=new Date(this.isoString);if(e.toString()==="Invalid Date")throw new RangeError("Fauna Date could not be converted to Javascript Date");return e}toString(){return`TimeStub("${this.isoString}")`}},b=class{dateString;constructor(e){this.dateString=e}static from(e){if(typeof e!="string")throw new TypeError(`Expected string but received ${typeof e}: ${e}`);let t=ge.exec(e);if(t===null)throw new RangeError(`Expected a plain date string but received '${e}'`);return new b(t[0])}static fromDate(e){let t=e.toISOString(),n=Te.exec(t);if(n===null)throw new y(`Failed to parse date '${e}'`);return new b(n[0])}toDate(){let e=new Date(this.dateString+"T00:00:00Z");if(e.toString()==="Invalid Date")throw new RangeError("Fauna Date could not be converted to Javascript Date");return e}toString(){return`DateStub("${this.dateString}")`}};var R=class{coll;id;constructor({coll:e,id:t}){this.id=t,typeof e=="string"?this.coll=new P(e):this.coll=e}},v=class extends R{ts;constructor(e){let{coll:t,id:n,ts:s,...o}=e;super({coll:t,id:n}),this.ts=s,Object.assign(this,o)}toObject(){return{...this}}},$=class{coll;name;constructor({coll:e,name:t}){this.name=t,typeof e=="string"?this.coll=new P(e):this.coll=e}},G=class extends ${ts;data;constructor(e){let{coll:t,name:n,ts:s,data:o,...i}=e;super({coll:t,name:n}),this.ts=s,this.data=o||{},Object.assign(this,i)}toObject(){return{...this}}},P=class{name;constructor(e){this.name=e}},z=class{ref;cause;constructor(e,t){this.ref=e,this.cause=t}};var x=class{data;after;constructor({data:e,after:t}){this.data=e,this.after=t}},C=class{after;constructor(e){this.after=e}},S=class{#e;constructor(e,t){if(t instanceof Function)this.#e=Ve(e,t);else if(t instanceof x||t instanceof C)this.#e=be(e,t);else throw new TypeError(`Expected 'Page<T> | EmbeddedSet | (() => Promise<T | Page<T> | EmbeddedSet>)', but received ${JSON.stringify(t)}`)}static fromQuery(e,t){return new S(e,async()=>(await e.query(t)).data)}static fromPageable(e,t){return new S(e,t)}flatten(){return new ue(this)}async next(){return this.#e.next()}async return(){return this.#e.return()}async throw(e){return this.#e.throw(e)}[Symbol.asyncIterator](){return this}},ue=class{#e;constructor(e){this.#e=ke(e)}async next(){return this.#e.next()}async return(){return this.#e.return()}async throw(e){return this.#e.throw(e)}[Symbol.asyncIterator](){return this}};async function*be(r,e){let t=e;for(t instanceof x&&(yield t.data);t.after;){let n=de`Set.paginate(${t.after})`;t=(await r.query(n)).data,yield t.data}}async function*Ve(r,e){let t=await e();if(t instanceof x||t instanceof C){for await(let n of be(r,t))yield n;return}yield[t]}async function*ke(r){for await(let e of r)for(let t of e)yield t}var H=class{static encode(e){return re(e)}static decode(e){return JSON.parse(e,(t,n)=>{if(n==null)return null;if(n["@mod"])return new P(n["@mod"]);if(n["@doc"]){if(typeof n["@doc"]=="string"){let[o,i]=n["@doc"].split(":");return new R({coll:o,id:i})}let s=n["@doc"];return s.id?new v(s):new G(s)}else if(n["@ref"]){let s=n["@ref"],o;return s.id?o=new R(s):o=new $(s),"exists"in s&&s.exists===!1?new z(o,s.cause):o}else{if(n["@set"])return typeof n["@set"]=="string"?new C(n["@set"]):new x(n["@set"]);if(n["@int"])return Number(n["@int"]);if(n["@long"])return BigInt(n["@long"]);if(n["@double"])return Number(n["@double"]);if(n["@date"])return b.from(n["@date"]);if(n["@time"])return h.from(n["@time"]);if(n["@object"])return n["@object"]}return n})}},xe=BigInt("-9223372036854775808"),Se=BigInt("9223372036854775807"),c={bigint:r=>{if(r<xe||r>Se)throw new RangeError("Precision loss when converting BigInt to Fauna type");return{"@long":r.toString()}},number:r=>{if(r===Number.POSITIVE_INFINITY||r===Number.NEGATIVE_INFINITY)throw new RangeError(`Cannot convert ${r} to a Fauna type.`);return`${r}`.includes(".")?{"@double":r.toString()}:r>=-(2**31)&&r<=2**31-1?{"@int":r.toString()}:Number.isSafeInteger(r)?{"@long":r.toString()}:{"@double":r.toString()}},string:r=>r,object:r=>{let e=!1,t={};for(let n in r)n.startsWith("@")&&(e=!0),r[n]!==void 0&&(t[n]=re(r[n]));return e?{"@object":t}:t},array:r=>{let e=[];for(let t in r)e.push(re(r[t]));return e},date:r=>({"@time":r.toISOString()}),faunadate:r=>({"@date":r.dateString}),faunatime:r=>({"@time":r.isoString}),module:r=>({"@mod":r.name}),documentReference:r=>({"@ref":{id:r.id,coll:{"@mod":r.coll.name}}}),document:r=>({"@ref":{id:r.id,coll:{"@mod":r.coll.name}}}),namedDocumentReference:r=>({"@ref":{name:r.name,coll:{"@mod":r.coll.name}}}),namedDocument:r=>({"@ref":{name:r.name,coll:{"@mod":r.coll.name}}}),set:r=>{throw new y("Page could not be encoded. Fauna does not accept encoded Set values, yet. Use Page.data and Page.after as arguments, instead.")}},re=r=>{if(r===void 0)throw new TypeError("Passing undefined as a QueryValue is not supported");switch(typeof r){case"bigint":return c.bigint(r);case"string":return c.string(r);case"number":return c.number(r);case"boolean":return r;case"object":return r==null?null:Array.isArray(r)?c.array(r):r instanceof Date?c.date(r):r instanceof b?c.faunadate(r):r instanceof h?c.faunatime(r):r instanceof P?c.module(r):r instanceof v?c.document(r):r instanceof R?c.documentReference(r):r instanceof G?c.namedDocument(r):r instanceof $?c.namedDocumentReference(r):r instanceof z?re(r.ref):r instanceof x||r instanceof C?c.set(r):c.object(r)}};function de(r,...e){return new j(r,...e)}var j=class{#e;#r;constructor(e,...t){if(e.length===0||e.length!==t.length+1)throw new Error("invalid query constructed");this.#e=e,this.#r=t}toQuery(e={}){return{...this.#t(e),...e}}#t(e){if(this.#e.length===1)return{query:{fql:[this.#e[0]]},arguments:{}};let t={};return{query:{fql:this.#e.flatMap((s,o)=>{if(o===this.#e.length-1)return s===""?[]:[s];let i=this.#r[o],d;if(i instanceof j){let u=i.toQuery(e);d=u.query,t={...t,...u.arguments}}else d={value:H.encode(i)};return[s,d].filter(u=>u!=="")})},arguments:t}}};var we=r=>r instanceof Object&&"data"in r,Qe=r=>r instanceof Object&&"error"in r&&r.error instanceof Object&&"code"in r.error&&"message"in r.error;var te=class{#e;constructor({url:e}){this.#e=new URL("/query/1",e).toString()}async request({data:e,headers:t,method:n,client_timeout_ms:s}){let o=new AbortController,i=o.signal;setTimeout(()=>o.abort(),s);let d=await fetch(this.#e,{method:n,headers:{...t,"Content-Type":"application/json"},body:JSON.stringify(e),signal:i}).catch(f=>{throw new p("The network connection encountered a problem.",{cause:f})}),u=d.status,l={};d.headers.forEach((f,w)=>l[w]=f);let m=await d.text();return{status:u,body:m,headers:l}}close(){}};var M;try{M=pe("node:http2")}catch{M=void 0}var q,K,Y,B,ne,se,Ee,L=class{constructor({http2_session_idle_ms:e,url:t}){U(this,B);U(this,se);U(this,K,void 0);U(this,Y,void 0);if(M===void 0)throw new Error("Your platform does not support Node's http2 library");ae(this,K,e),ae(this,Y,t)}async request({client_timeout_ms:e,data:t,headers:n,method:s}){let o,i=new Promise((d,u)=>{let l=m=>{let f=Number(m[M.constants.HTTP2_HEADER_STATUS]),w="";o.on("data",_e=>{w+=_e}),o.on("end",()=>{d({status:f,body:w,headers:m})})};try{let m={...n,[M.constants.HTTP2_HEADER_PATH]:"/query/1",[M.constants.HTTP2_HEADER_METHOD]:s};o=W(this,se,Ee).call(this).request(m).setEncoding("utf8").on("error",w=>{u(w)}).on("response",l),o.write(JSON.stringify(t),"utf8"),o.setTimeout(e,()=>{o.destroy(new Error("Client timeout"))}),o.end()}catch(m){u(m)}});try{return await i}catch(d){throw new p("The network connection encountered a problem.",{cause:d})}}close(){let e=g(L,q).get(this.sessionKey);if(!!e&&(e.refs.delete(this),e.refs.size===0)){let t=e.session;t&&!t.closed&&t.close(),e.session=null}}isClosed(){return(g(L,q).get(this.sessionKey)?.refs.size??0)===0}get sessionKey(){return`${g(this,Y)}|${g(this,K)}`}},J=L;q=new WeakMap,K=new WeakMap,Y=new WeakMap,B=new WeakSet,ne=function(){let e=g(L,q).get(this.sessionKey);if(!e)return;e.refs.clear();let t=e.session;t&&!t.closed&&t.close(),e.session=null},se=new WeakSet,Ee=function(){let e=g(L,q).get(this.sessionKey);if(e||(e={session:null,refs:new Set},g(L,q).set(this.sessionKey,e)),e.session===null||e.session.closed){let t=g(this,K),n=g(this,Y),s=M.connect(n).once("error",()=>W(this,B,ne).call(this)).once("goaway",()=>W(this,B,ne).call(this));s.setTimeout(t,()=>{W(this,B,ne).call(this)}),e.session=s}return e.refs.add(this),e.session},U(J,q,new Map);var le=r=>Fe()?new J(r):new te(r),me=r=>r instanceof Object&&"body"in r&&"headers"in r&&"status"in r,Fe=()=>{if(typeof process<"u"&&process.release?.name==="node")try{return pe("node:http2"),!0}catch{return!1}return!1};var Oe={client_timeout_buffer_ms:5e3,endpoint:ie.default,format:"tagged",http2_session_idle_ms:500,max_conns:10,query_timeout_ms:5e3},ye=class{#e;#r;#t;#n=!1;constructor(e,t){this.#e={...Oe,...e,secret:this.#o(e)},this.#u(),t?this.#r=t:this.#r=le({url:this.#e.endpoint.toString(),http2_session_idle_ms:this.#e.http2_session_idle_ms})}get lastTxnTs(){return this.#t}set lastTxnTs(e){this.#t=this.#t?Math.max(e,this.#t):e}get clientConfiguration(){let{secret:e,...t}=this.#e;return t}close(){if(this.#n)throw new _("Your client is closed. You cannot close it again.");this.#r.close(),this.#n=!0}paginate(e){return e instanceof j?S.fromQuery(this,e):S.fromPageable(this,e)}async query(e,t){if(this.#n)throw new _("Your client is closed. No further requests can be issued.");return this.#i(e.toQuery(t))}#s(e){if(e instanceof y||e instanceof p||e instanceof T||e instanceof a)return e;if(me(e)){if(Qe(e.body)){let t=e.body,n=e.status;return this.#a(t,n)}return new T({message:`Response is in an unkown format: ${e.body}`,httpStatus:e.status})}return new y("A client level error occurred. Fauna was not called.",{cause:e})}#o(e){let t;typeof process=="object"&&(t=process.env.FAUNA_SECRET);let n=e?.secret||t;if(n===void 0)throw new Error("You must provide a secret to the driver. Set it in an environmental variable named FAUNA_SECRET or pass it to the Client constructor.");return n}#a(e,t){switch(t){case 400:return Ne.includes(e.error.code)?new Q(e,t):e.error.code==="invalid_request"?new E(e,t):e.error.code==="abort"&&e.error.abort!==void 0?new X(e,t):new I(e,t);case 401:return new V(e,t);case 403:return new k(e,t);case 409:return new Z(e,t);case 429:return new F(e,t);case 440:return new O(e,t);case 500:return new N(e,t);case 503:return new A(e,t);default:return new a(e,t)}}async#i(e){try{let t={Authorization:`Bearer ${this.#e.secret}`};this.#c({...this.clientConfiguration,...e},t);let n={...this.#e,...e},s=n.format==="tagged"||e.format==="tagged",o=s?H.encode(e.arguments):e.arguments,i={query:e.query,arguments:o},d=n.query_timeout_ms+this.#e.client_timeout_buffer_ms,u=await this.#r.request({data:i,headers:t,method:"POST",client_timeout_ms:d}),l;try{if(l={...u,body:s?H.decode(u.body):JSON.parse(u.body)},l.body.query_tags){let f=l.body.query_tags.split(",").map(w=>w.split("="));l.body.query_tags=Object.fromEntries(f)}}catch(f){throw new T({message:`Error parsing response as JSON: ${f}`,httpStatus:u.status})}if(!we(l.body))throw this.#s(l);let m=l.body.txn_ts;return(this.#t===void 0&&m!==void 0||m!==void 0&&this.#t!==void 0&&this.#t<m)&&(this.#t=m),l.body}catch(t){throw this.#s(t)}}#c(e,t){for(let n of Object.entries(e))if(["format","query_timeout_ms","linearized","max_contention_retries","traceparent","typecheck","query_tags"].includes(n[0])){let s,o=`x-${n[0].replaceAll("_","-")}`;n[0]==="query_tags"?s=Object.entries(n[1]).map(i=>i.join("=")).join(","):typeof n[1]=="string"?s=n[1]:s=String(n[1]),n[0]==="traceparent"&&(o=n[0]),t[o]=s}t["x-last-txn-ts"]===void 0&&this.#t!==void 0&&(t["x-last-txn-ts"]=this.#t)}#u(){let e=this.#e;if(["client_timeout_buffer_ms","endpoint","format","http2_session_idle_ms","max_conns","query_timeout_ms"].forEach(n=>{if(e[n]===void 0)throw new TypeError(`ClientConfiguration option '${n}' must be defined.`)}),e.client_timeout_buffer_ms<=0)throw new RangeError("'client_timeout_buffer_ms' must be greater than zero.");if(e.query_timeout_ms<=0)throw new RangeError("'query_timeout_ms' must be greater than zero.")}},Ne=["invalid_function_definition","invalid_identifier","invalid_query","invalid_syntax","invalid_type"];export{X as AbortError,V as AuthenticationError,k as AuthorizationError,ye as Client,_ as ClientClosedError,y as ClientError,Z as ContendedTransactionError,b as DateStub,v as Document,R as DocumentReference,C as EmbeddedSet,te as FetchClient,E as InvalidRequestError,Se as LONG_MAX,xe as LONG_MIN,P as Module,G as NamedDocument,$ as NamedDocumentReference,p as NetworkError,J as NodeHTTP2Client,z as NullDocument,x as Page,T as ProtocolError,Q as QueryCheckError,I as QueryRuntimeError,O as QueryTimeoutError,a as ServiceError,N as ServiceInternalError,A as ServiceTimeoutError,S as SetIterator,H as TaggedTypeFormat,F as ThrottlingError,h as TimeStub,ie as endpoints,de as fql,le as getDefaultHTTPClient,me as isHTTPResponse};
var be=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+r+'" is not supported')});var de=(r,e,t)=>{if(!e.has(r))throw TypeError("Cannot "+t)};var u=(r,e,t)=>(de(r,e,"read from private field"),t?t.call(r):e.get(r)),g=(r,e,t)=>{if(e.has(r))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(r):e.set(r,t)},I=(r,e,t,n)=>(de(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t),le=(r,e,t,n)=>({set _(s){I(r,e,s,t)},get _(){return u(r,e,n)}}),k=(r,e,t)=>(de(r,e,"access private method"),t);var me={default:new URL("https://db.fauna.com"),local:new URL("http://localhost:8443"),localhost:new URL("http://localhost:8443")};var V=class extends Error{constructor(...e){super(...e)}},i=class extends V{httpStatus;code;queryInfo;constraint_failures;constructor(e,t){super(e.error.message),Error.captureStackTrace&&Error.captureStackTrace(this,i),this.name="ServiceError",this.code=e.error.code,this.httpStatus=t;let n={txn_ts:e.txn_ts,summary:e.summary,query_tags:e.query_tags,stats:e.stats};this.queryInfo=n,this.constraint_failures=e.error.constraint_failures}},F=class extends i{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,F),this.name="QueryRuntimeError"}},Q=class extends i{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,Q),this.name="QueryCheckError"}},R=class extends i{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,R),this.name="InvalidRequestError"}},X=class extends i{abort;constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,Q),this.name="AbortError",this.abort=e.error.abort}},O=class extends i{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,O),this.name="AuthenticationError"}},N=class extends i{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,N),this.name="AuthorizationError"}},Z=class extends i{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,R),this.name="ContendedTransactionError"}},A=class extends i{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,A),this.name="ThrottlingError"}},$=class extends i{stats;constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,$),this.name="QueryTimeoutError",this.stats=e.stats}},j=class extends i{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,j),this.name="ServiceInternalError"}},M=class extends i{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,M),this.name="ServiceTimeoutError"}},p=class extends V{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,p),this.name="ClientError"}},_=class extends V{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,_),this.name="ClientClosedError"}},f=class extends V{constructor(e,t){super(e,t),Error.captureStackTrace&&Error.captureStackTrace(this,f),this.name="NetworkError"}},h=class extends V{httpStatus;constructor(e){super(e.message),Error.captureStackTrace&&Error.captureStackTrace(this,h),this.name="ProtocolError",this.httpStatus=e.httpStatus}};var Ie=/(?:\d{4}|[\u2212-]\d{4,}|\+\d{5,})/,ke=/(?:0[1-9]|1[0-2])/,Ve=/(?:0[1-9]|[12]\d|3[01])/,xe=/(?:[01][0-9]|2[0-3])/,ee=/(?:[0-5][0-9])/,Fe=/(?:\.\d+)/,ye=new RegExp(`(${Ie.source}-(${ke.source})-(${Ve.source}))`),Oe=new RegExp(`(${xe.source}:${ee.source}:${ee.source}${Fe.source}?)`),Ne=new RegExp(`([zZ]|[+\u2212-]${xe.source}(?::?${ee.source}|:${ee.source}:${ee.source}))`),Se=new RegExp(`^${ye.source}$`),we=new RegExp(`^${ye.source}`),Ee=new RegExp(`^${ye.source}T${Oe.source}${Ne.source}$`);var b=class{isoString;constructor(e){this.isoString=e}static from(e){if(typeof e!="string")throw new TypeError(`Expected string but received ${typeof e}: ${e}`);if(Ee.exec(e)===null)throw new RangeError(`(regex) Expected an ISO date string but received '${e}'`);return new b(e)}static fromDate(e){return new b(e.toISOString())}toDate(){let e=new Date(this.isoString);if(e.toString()==="Invalid Date")throw new RangeError("Fauna Date could not be converted to Javascript Date");return e}toString(){return`TimeStub("${this.isoString}")`}},x=class{dateString;constructor(e){this.dateString=e}static from(e){if(typeof e!="string")throw new TypeError(`Expected string but received ${typeof e}: ${e}`);let t=Se.exec(e);if(t===null)throw new RangeError(`Expected a plain date string but received '${e}'`);return new x(t[0])}static fromDate(e){let t=e.toISOString(),n=we.exec(t);if(n===null)throw new p(`Failed to parse date '${e}'`);return new x(n[0])}toDate(){let e=new Date(this.dateString+"T00:00:00Z");if(e.toString()==="Invalid Date")throw new RangeError("Fauna Date could not be converted to Javascript Date");return e}toString(){return`DateStub("${this.dateString}")`}};var P=class{coll;id;constructor({coll:e,id:t}){this.id=t,typeof e=="string"?this.coll=new C(e):this.coll=e}},Y=class extends P{ts;constructor(e){let{coll:t,id:n,ts:s,...o}=e;super({coll:t,id:n}),this.ts=s,Object.assign(this,o)}toObject(){return{...this}}},L=class{coll;name;constructor({coll:e,name:t}){this.name=t,typeof e=="string"?this.coll=new C(e):this.coll=e}},J=class extends L{ts;data;constructor(e){let{coll:t,name:n,ts:s,data:o,...c}=e;super({coll:t,name:n}),this.ts=s,this.data=o||{},Object.assign(this,c)}toObject(){return{...this}}},C=class{name;constructor(e){this.name=e}},B=class{ref;cause;constructor(e,t){this.ref=e,this.cause=t}};var S=class{data;after;constructor({data:e,after:t}){this.data=e,this.after=t}},H=class{after;constructor(e){this.after=e}},w=class{#e;constructor(e,t){if(t instanceof Function)this.#e=$e(e,t);else if(t instanceof S||t instanceof H)this.#e=Qe(e,t);else throw new TypeError(`Expected 'Page<T> | EmbeddedSet | (() => Promise<T | Page<T> | EmbeddedSet>)', but received ${JSON.stringify(t)}`)}static fromQuery(e,t){return new w(e,async()=>(await e.query(t)).data)}static fromPageable(e,t){return new w(e,t)}flatten(){return new pe(this)}async next(){return this.#e.next()}async return(){return this.#e.return()}async throw(e){return this.#e.throw(e)}[Symbol.asyncIterator](){return this}},pe=class{#e;constructor(e){this.#e=je(e)}async next(){return this.#e.next()}async return(){return this.#e.return()}async throw(e){return this.#e.throw(e)}[Symbol.asyncIterator](){return this}};async function*Qe(r,e){let t=e;for(t instanceof S&&(yield t.data);t.after;){let n=fe`Set.paginate(${t.after})`;t=(await r.query(n)).data,yield t.data}}async function*$e(r,e){let t=await e();if(t instanceof S||t instanceof H){for await(let n of Qe(r,t))yield n;return}yield[t]}async function*je(r){for await(let e of r)for(let t of e)yield t}var q=class{static encode(e){return se(e)}static decode(e){return JSON.parse(e,(t,n)=>{if(n==null)return null;if(n["@mod"])return new C(n["@mod"]);if(n["@doc"]){if(typeof n["@doc"]=="string"){let[o,c]=n["@doc"].split(":");return new P({coll:o,id:c})}let s=n["@doc"];return s.id?new Y(s):new J(s)}else if(n["@ref"]){let s=n["@ref"],o;return s.id?o=new P(s):o=new L(s),"exists"in s&&s.exists===!1?new B(o,s.cause):o}else{if(n["@set"])return typeof n["@set"]=="string"?new H(n["@set"]):new S(n["@set"]);if(n["@int"])return Number(n["@int"]);if(n["@long"])return BigInt(n["@long"]);if(n["@double"])return Number(n["@double"]);if(n["@date"])return x.from(n["@date"]);if(n["@time"])return b.from(n["@time"]);if(n["@object"])return n["@object"]}return n})}},Re=BigInt("-9223372036854775808"),_e=BigInt("9223372036854775807"),l={bigint:r=>{if(r<Re||r>_e)throw new RangeError("Precision loss when converting BigInt to Fauna type");return{"@long":r.toString()}},number:r=>{if(r===Number.POSITIVE_INFINITY||r===Number.NEGATIVE_INFINITY)throw new RangeError(`Cannot convert ${r} to a Fauna type.`);return`${r}`.includes(".")?{"@double":r.toString()}:r>=-(2**31)&&r<=2**31-1?{"@int":r.toString()}:Number.isSafeInteger(r)?{"@long":r.toString()}:{"@double":r.toString()}},string:r=>r,object:r=>{let e=!1,t={};for(let n in r)n.startsWith("@")&&(e=!0),r[n]!==void 0&&(t[n]=se(r[n]));return e?{"@object":t}:t},array:r=>{let e=[];for(let t in r)e.push(se(r[t]));return e},date:r=>({"@time":r.toISOString()}),faunadate:r=>({"@date":r.dateString}),faunatime:r=>({"@time":r.isoString}),module:r=>({"@mod":r.name}),documentReference:r=>({"@ref":{id:r.id,coll:{"@mod":r.coll.name}}}),document:r=>({"@ref":{id:r.id,coll:{"@mod":r.coll.name}}}),namedDocumentReference:r=>({"@ref":{name:r.name,coll:{"@mod":r.coll.name}}}),namedDocument:r=>({"@ref":{name:r.name,coll:{"@mod":r.coll.name}}}),set:r=>{throw new p("Page could not be encoded. Fauna does not accept encoded Set values, yet. Use Page.data and Page.after as arguments, instead.")}},se=r=>{if(r===void 0)throw new TypeError("Passing undefined as a QueryValue is not supported");switch(typeof r){case"bigint":return l.bigint(r);case"string":return l.string(r);case"number":return l.number(r);case"boolean":return r;case"object":return r==null?null:Array.isArray(r)?l.array(r):r instanceof Date?l.date(r):r instanceof x?l.faunadate(r):r instanceof b?l.faunatime(r):r instanceof C?l.module(r):r instanceof Y?l.document(r):r instanceof P?l.documentReference(r):r instanceof J?l.namedDocument(r):r instanceof L?l.namedDocumentReference(r):r instanceof B?se(r.ref):r instanceof S||r instanceof H?l.set(r):l.object(r)}};function fe(r,...e){return new U(r,...e)}var U=class{#e;#r;constructor(e,...t){if(e.length===0||e.length!==t.length+1)throw new Error("invalid query constructed");this.#e=e,this.#r=t}toQuery(e={}){return{...this.#t(e),...e}}#t(e){if(this.#e.length===1)return{query:{fql:[this.#e[0]]},arguments:{}};let t={};return{query:{fql:this.#e.flatMap((s,o)=>{if(o===this.#e.length-1)return s===""?[]:[s];let c=this.#r[o],d;if(c instanceof U){let y=c.toQuery(e);d=y.query,t={...t,...y.arguments}}else d={value:q.encode(c)};return[s,d].filter(y=>y!=="")})},arguments:t}}};var Pe=r=>r instanceof Object&&"data"in r,Ce=r=>r instanceof Object&&"error"in r&&r.error instanceof Object&&"code"in r.error&&"message"in r.error;var te=class{#e;constructor({url:e}){this.#e=new URL("/query/1",e).toString()}async request({data:e,headers:t,method:n,client_timeout_ms:s}){let o=await fetch(this.#e,{method:n,headers:{...t,"Content-Type":"application/json"},body:JSON.stringify(e),signal:AbortSignal.timeout(s)}).catch(a=>{throw new f("The network connection encountered a problem.",{cause:a})}),c=o.status,d={};o.headers.forEach((a,T)=>d[T]=a);let y=await o.text();return{status:c,body:y,headers:d}}close(){}};var v;try{v=be("node:http2")}catch{v=void 0}var K,re,ne,D,m,ae,He,W,oe,ie,qe,ue,De,G=class{constructor({http2_session_idle_ms:e,url:t}){g(this,W);g(this,ie);g(this,ue);g(this,re,void 0);g(this,ne,void 0);g(this,D,0);g(this,m,void 0);if(v===void 0)throw new Error("Your platform does not support Node's http2 library");I(this,re,e),I(this,ne,t),I(this,m,null)}static getClient(e){var s;let t=k(s=G,ae,He).call(s,e);u(G,K).has(t)||u(G,K).set(t,new G(e));let n=u(G,K).get(t);return le(n,D)._++,n}async request(e){let t=0,n;do try{return await k(this,ue,De).call(this,e)}catch(s){if(s?.code!=="ERR_HTTP2_GOAWAY_SESSION")throw new f("The network connection encountered a problem.",{cause:s});n=s,t++}while(t<3);throw new f("The network connection encountered a problem.",{cause:n})}close(){this.isClosed()||(le(this,D)._--,u(this,D)===0&&u(this,m)&&!u(this,m).closed&&u(this,m).close())}isClosed(){return u(this,D)===0}},z=G;K=new WeakMap,re=new WeakMap,ne=new WeakMap,D=new WeakMap,m=new WeakMap,ae=new WeakSet,He=function({http2_session_idle_ms:e,url:t}){return`${t}|${e}`},W=new WeakSet,oe=function(){I(this,D,0),u(this,m)&&!u(this,m).closed&&u(this,m).close()},ie=new WeakSet,qe=function(){if(!u(this,m)||u(this,m).closed){let e=v.connect(u(this,ne)).once("error",()=>k(this,W,oe).call(this)).once("goaway",()=>k(this,W,oe).call(this));e.setTimeout(u(this,re),()=>{k(this,W,oe).call(this)}),I(this,m,e)}return u(this,m)},ue=new WeakSet,De=function({client_timeout_ms:e,data:t,headers:n,method:s}){return new Promise((o,c)=>{let d,y=a=>{let T=Number(a[v.constants.HTTP2_HEADER_STATUS]),E="";d.on("data",ce=>{E+=ce}),d.on("end",()=>{o({status:T,body:E,headers:a})})};try{let a={...n,[v.constants.HTTP2_HEADER_PATH]:"/query/1",[v.constants.HTTP2_HEADER_METHOD]:s};d=k(this,ie,qe).call(this).request(a).setEncoding("utf8").on("error",E=>{c(E)}).on("response",y),d.write(JSON.stringify(t),"utf8"),d.setTimeout(e,()=>{d.destroy(new Error("Client timeout"))}),d.end()}catch(a){c(a)}})},g(z,ae),g(z,K,new Map);var ge=r=>Me()?z.getClient(r):new te(r),Te=r=>r instanceof Object&&"body"in r&&"headers"in r&&"status"in r,Me=()=>{if(typeof process<"u"&&process.release?.name==="node")try{return be("node:http2"),!0}catch{return!1}return!1};var Le={client_timeout_buffer_ms:5e3,endpoint:me.default,format:"tagged",http2_session_idle_ms:5e3,max_conns:10,query_timeout_ms:5e3},he=class{#e;#r;#t;#n=!1;constructor(e,t){this.#e={...Le,...e,secret:this.#o(e)},this.#c(),t?this.#r=t:this.#r=ge({url:this.#e.endpoint.toString(),http2_session_idle_ms:this.#e.http2_session_idle_ms})}get lastTxnTs(){return this.#t}set lastTxnTs(e){this.#t=this.#t?Math.max(e,this.#t):e}get clientConfiguration(){let{secret:e,...t}=this.#e;return t}close(){if(this.#n)throw new _("Your client is closed. You cannot close it again.");this.#r.close(),this.#n=!0}paginate(e){return e instanceof U?w.fromQuery(this,e):w.fromPageable(this,e)}async query(e,t){if(this.#n)throw new _("Your client is closed. No further requests can be issued.");return this.#i(e.toQuery(t))}#s(e){if(e instanceof p||e instanceof f||e instanceof h||e instanceof i)return e;if(Te(e)){if(Ce(e.body)){let t=e.body,n=e.status;return this.#a(t,n)}return new h({message:`Response is in an unkown format: ${e.body}`,httpStatus:e.status})}return new p("A client level error occurred. Fauna was not called.",{cause:e})}#o(e){let t;typeof process=="object"&&(t=process.env.FAUNA_SECRET);let n=e?.secret||t;if(n===void 0)throw new Error("You must provide a secret to the driver. Set it in an environmental variable named FAUNA_SECRET or pass it to the Client constructor.");return n}#a(e,t){switch(t){case 400:return Ue.includes(e.error.code)?new Q(e,t):e.error.code==="invalid_request"?new R(e,t):e.error.code==="abort"&&e.error.abort!==void 0?new X(e,t):new F(e,t);case 401:return new O(e,t);case 403:return new N(e,t);case 409:return new Z(e,t);case 429:return new A(e,t);case 440:return new $(e,t);case 500:return new j(e,t);case 503:return new M(e,t);default:return new i(e,t)}}async#i(e){try{let t={Authorization:`Bearer ${this.#e.secret}`};this.#u({...this.clientConfiguration,...e},t);let n={...this.#e,...e},s=n.format==="tagged"||e.format==="tagged",o=s?q.encode(e.arguments):e.arguments,c={query:e.query,arguments:o},d=n.query_timeout_ms+this.#e.client_timeout_buffer_ms,y=await this.#r.request({data:c,headers:t,method:"POST",client_timeout_ms:d}),a;try{if(a={...y,body:s?q.decode(y.body):JSON.parse(y.body)},a.body.query_tags){let E=a.body.query_tags.split(",").map(ce=>ce.split("="));a.body.query_tags=Object.fromEntries(E)}}catch(E){throw new h({message:`Error parsing response as JSON: ${E}`,httpStatus:y.status})}if(!Pe(a.body))throw this.#s(a);let T=a.body.txn_ts;return(this.#t===void 0&&T!==void 0||T!==void 0&&this.#t!==void 0&&this.#t<T)&&(this.#t=T),a.body}catch(t){throw this.#s(t)}}#u(e,t){for(let n of Object.entries(e))if(["format","query_timeout_ms","linearized","max_contention_retries","traceparent","typecheck","query_tags"].includes(n[0])){let s,o=`x-${n[0].replaceAll("_","-")}`;n[0]==="query_tags"?s=Object.entries(n[1]).map(c=>c.join("=")).join(","):typeof n[1]=="string"?s=n[1]:s=String(n[1]),n[0]==="traceparent"&&(o=n[0]),t[o]=s}t["x-last-txn-ts"]===void 0&&this.#t!==void 0&&(t["x-last-txn-ts"]=this.#t)}#c(){let e=this.#e;if(["client_timeout_buffer_ms","endpoint","format","http2_session_idle_ms","max_conns","query_timeout_ms"].forEach(n=>{if(e[n]===void 0)throw new TypeError(`ClientConfiguration option '${n}' must be defined.`)}),e.client_timeout_buffer_ms<=0)throw new RangeError("'client_timeout_buffer_ms' must be greater than zero.");if(e.query_timeout_ms<=0)throw new RangeError("'query_timeout_ms' must be greater than zero.")}},Ue=["invalid_function_definition","invalid_identifier","invalid_query","invalid_syntax","invalid_type"];export{X as AbortError,O as AuthenticationError,N as AuthorizationError,he as Client,_ as ClientClosedError,p as ClientError,Z as ContendedTransactionError,x as DateStub,Y as Document,P as DocumentReference,H as EmbeddedSet,te as FetchClient,R as InvalidRequestError,_e as LONG_MAX,Re as LONG_MIN,C as Module,J as NamedDocument,L as NamedDocumentReference,f as NetworkError,z as NodeHTTP2Client,B as NullDocument,S as Page,h as ProtocolError,Q as QueryCheckError,F as QueryRuntimeError,$ as QueryTimeoutError,i as ServiceError,j as ServiceInternalError,M as ServiceTimeoutError,w as SetIterator,q as TaggedTypeFormat,A as ThrottlingError,b as TimeStub,me as endpoints,fe as fql,ge as getDefaultHTTPClient,Te as isHTTPResponse};
//# sourceMappingURL=index.js.map

@@ -38,3 +38,3 @@ import { ValueFormat } from "./wire-protocol";

* Time in milliseconds the client will keep an HTTP2 session open after all
* requests are completed. The default is 500 ms.
* requests are completed. The default is 5000 ms.
*/

@@ -41,0 +41,0 @@ http2_session_idle_ms: number;

@@ -7,5 +7,12 @@ import { HTTPClient, HTTPClientOptions, HTTPRequest, HTTPResponse } from "./http-client";

#private;
constructor({ http2_session_idle_ms, url }: HTTPClientOptions);
private constructor();
/**
* Gets a {@link NodeHTTP2Client} matching the {@link HTTTPClientOptions}
* @param httpClientOptions - the {@link HTTTPClientOptions}
* @returns a {@link NodeHTTP2Client} matching the {@link HTTTPClientOptions}
*/
static getClient(httpClientOptions: HTTPClientOptions): NodeHTTP2Client;
/** {@inheritDoc HTTPClient.request} */
request({ client_timeout_ms, data: requestData, headers: requestHeaders, method, }: HTTPRequest): Promise<HTTPResponse>;
request(req: HTTPRequest): Promise<HTTPResponse>;
/** {@inheritDoc HTTPClient.close} */
close(): void;

@@ -16,6 +23,2 @@ /**

isClosed(): boolean;
/**
* Creates a key common the client that should share the same session
*/
get sessionKey(): string;
}

@@ -37,2 +37,10 @@ "use strict";

};
var __privateWrapper = (obj, member, setter, getter) => ({
set _(value) {
__privateSet(obj, member, value, setter);
},
get _() {
return __privateGet(obj, member, getter);
}
});
var __privateMethod = (obj, member, method) => {

@@ -774,5 +782,2 @@ __accessCheck(obj, member, "access private method");

}) {
const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => controller.abort(), client_timeout_ms);
const response = await fetch(this.#url, {

@@ -782,3 +787,3 @@ method,

body: JSON.stringify(data),
signal
signal: AbortSignal.timeout(client_timeout_ms)
}).catch((error) => {

@@ -810,3 +815,3 @@ throw new NetworkError("The network connection encountered a problem.", {

}
var _sessionMap, _http2_session_idle_ms, _url, _closeForAll, closeForAll_fn, _connect, connect_fn;
var _clients, _http2_session_idle_ms, _url, _numberOfUsers, _session, _getClientKey, getClientKey_fn, _closeForAll, closeForAll_fn, _connect, connect_fn, _doRequest, doRequest_fn;
var _NodeHTTP2Client = class {

@@ -816,4 +821,7 @@ constructor({ http2_session_idle_ms, url }) {

__privateAdd(this, _connect);
__privateAdd(this, _doRequest);
__privateAdd(this, _http2_session_idle_ms, void 0);
__privateAdd(this, _url, void 0);
__privateAdd(this, _numberOfUsers, 0);
__privateAdd(this, _session, void 0);
if (http2 === void 0) {

@@ -824,117 +832,131 @@ throw new Error("Your platform does not support Node's http2 library");

__privateSet(this, _url, url);
__privateSet(this, _session, null);
}
async request({
client_timeout_ms,
data: requestData,
headers: requestHeaders,
method
}) {
let req;
const requestPromise = new Promise(
(resolvePromise, rejectPromise) => {
const onResponse = (http2ResponseHeaders) => {
const status = Number(
http2ResponseHeaders[http2.constants.HTTP2_HEADER_STATUS]
static getClient(httpClientOptions) {
var _a;
const clientKey = __privateMethod(_a = _NodeHTTP2Client, _getClientKey, getClientKey_fn).call(_a, httpClientOptions);
if (!__privateGet(_NodeHTTP2Client, _clients).has(clientKey)) {
__privateGet(_NodeHTTP2Client, _clients).set(
clientKey,
new _NodeHTTP2Client(httpClientOptions)
);
}
const client = __privateGet(_NodeHTTP2Client, _clients).get(clientKey);
__privateWrapper(client, _numberOfUsers)._++;
return client;
}
async request(req) {
let retryCount = 0;
let memoizedError;
do {
try {
return await __privateMethod(this, _doRequest, doRequest_fn).call(this, req);
} catch (error) {
if (error?.code !== "ERR_HTTP2_GOAWAY_SESSION") {
throw new NetworkError(
"The network connection encountered a problem.",
{
cause: error
}
);
let responseData = "";
req.on("data", (chunk) => {
responseData += chunk;
});
req.on("end", () => {
resolvePromise({
status,
body: responseData,
headers: http2ResponseHeaders
});
});
};
try {
const httpRequestHeaders = {
...requestHeaders,
[http2.constants.HTTP2_HEADER_PATH]: "/query/1",
[http2.constants.HTTP2_HEADER_METHOD]: method
};
const session = __privateMethod(this, _connect, connect_fn).call(this);
req = session.request(httpRequestHeaders).setEncoding("utf8").on("error", (error) => {
rejectPromise(error);
}).on("response", onResponse);
req.write(JSON.stringify(requestData), "utf8");
req.setTimeout(client_timeout_ms, () => {
req.destroy(new Error(`Client timeout`));
});
req.end();
} catch (error) {
rejectPromise(error);
}
memoizedError = error;
retryCount++;
}
);
try {
return await requestPromise;
} catch (error) {
throw new NetworkError("The network connection encountered a problem.", {
cause: error
});
}
} while (retryCount < 3);
throw new NetworkError("The network connection encountered a problem.", {
cause: memoizedError
});
}
close() {
const session_rc = __privateGet(_NodeHTTP2Client, _sessionMap).get(this.sessionKey);
if (!session_rc)
if (this.isClosed()) {
return;
session_rc.refs.delete(this);
if (session_rc.refs.size === 0) {
const session = session_rc.session;
if (session && !session.closed)
session.close();
session_rc.session = null;
}
__privateWrapper(this, _numberOfUsers)._--;
if (__privateGet(this, _numberOfUsers) === 0 && __privateGet(this, _session) && !__privateGet(this, _session).closed) {
__privateGet(this, _session).close();
}
}
isClosed() {
const session_rc = __privateGet(_NodeHTTP2Client, _sessionMap).get(this.sessionKey);
return (session_rc?.refs.size ?? 0) === 0;
return __privateGet(this, _numberOfUsers) === 0;
}
get sessionKey() {
return `${__privateGet(this, _url)}|${__privateGet(this, _http2_session_idle_ms)}`;
}
};
var NodeHTTP2Client = _NodeHTTP2Client;
_sessionMap = new WeakMap();
_clients = new WeakMap();
_http2_session_idle_ms = new WeakMap();
_url = new WeakMap();
_numberOfUsers = new WeakMap();
_session = new WeakMap();
_getClientKey = new WeakSet();
getClientKey_fn = function({ http2_session_idle_ms, url }) {
return `${url}|${http2_session_idle_ms}`;
};
_closeForAll = new WeakSet();
closeForAll_fn = function() {
const session_rc = __privateGet(_NodeHTTP2Client, _sessionMap).get(this.sessionKey);
if (!session_rc)
return;
session_rc.refs.clear();
const session = session_rc.session;
if (session && !session.closed)
session.close();
session_rc.session = null;
__privateSet(this, _numberOfUsers, 0);
if (__privateGet(this, _session) && !__privateGet(this, _session).closed) {
__privateGet(this, _session).close();
}
};
_connect = new WeakSet();
connect_fn = function() {
let session_rc = __privateGet(_NodeHTTP2Client, _sessionMap).get(this.sessionKey);
if (!session_rc) {
session_rc = {
session: null,
refs: /* @__PURE__ */ new Set()
};
__privateGet(_NodeHTTP2Client, _sessionMap).set(this.sessionKey, session_rc);
}
if (session_rc.session === null || session_rc.session.closed) {
const http2_session_idle_ms = __privateGet(this, _http2_session_idle_ms);
const url = __privateGet(this, _url);
const new_session = http2.connect(url).once("error", () => __privateMethod(this, _closeForAll, closeForAll_fn).call(this)).once("goaway", () => __privateMethod(this, _closeForAll, closeForAll_fn).call(this));
new_session.setTimeout(http2_session_idle_ms, () => {
if (!__privateGet(this, _session) || __privateGet(this, _session).closed) {
const new_session = http2.connect(__privateGet(this, _url)).once("error", () => __privateMethod(this, _closeForAll, closeForAll_fn).call(this)).once("goaway", () => __privateMethod(this, _closeForAll, closeForAll_fn).call(this));
new_session.setTimeout(__privateGet(this, _http2_session_idle_ms), () => {
__privateMethod(this, _closeForAll, closeForAll_fn).call(this);
});
session_rc.session = new_session;
__privateSet(this, _session, new_session);
}
session_rc.refs.add(this);
return session_rc.session;
return __privateGet(this, _session);
};
__privateAdd(NodeHTTP2Client, _sessionMap, /* @__PURE__ */ new Map());
_doRequest = new WeakSet();
doRequest_fn = function({
client_timeout_ms,
data: requestData,
headers: requestHeaders,
method
}) {
return new Promise((resolvePromise, rejectPromise) => {
let req;
const onResponse = (http2ResponseHeaders) => {
const status = Number(
http2ResponseHeaders[http2.constants.HTTP2_HEADER_STATUS]
);
let responseData = "";
req.on("data", (chunk) => {
responseData += chunk;
});
req.on("end", () => {
resolvePromise({
status,
body: responseData,
headers: http2ResponseHeaders
});
});
};
try {
const httpRequestHeaders = {
...requestHeaders,
[http2.constants.HTTP2_HEADER_PATH]: "/query/1",
[http2.constants.HTTP2_HEADER_METHOD]: method
};
const session = __privateMethod(this, _connect, connect_fn).call(this);
req = session.request(httpRequestHeaders).setEncoding("utf8").on("error", (error) => {
rejectPromise(error);
}).on("response", onResponse);
req.write(JSON.stringify(requestData), "utf8");
req.setTimeout(client_timeout_ms, () => {
req.destroy(new Error(`Client timeout`));
});
req.end();
} catch (error) {
rejectPromise(error);
}
});
};
__privateAdd(NodeHTTP2Client, _getClientKey);
__privateAdd(NodeHTTP2Client, _clients, /* @__PURE__ */ new Map());
// src/http-client/index.ts
var getDefaultHTTPClient = (options) => isNode() ? new NodeHTTP2Client(options) : new FetchClient(options);
var getDefaultHTTPClient = (options) => isNode() ? NodeHTTP2Client.getClient(options) : new FetchClient(options);
var isHTTPResponse = (res) => res instanceof Object && "body" in res && "headers" in res && "status" in res;

@@ -958,3 +980,3 @@ var isNode = () => {

format: "tagged",
http2_session_idle_ms: 500,
http2_session_idle_ms: 5e3,
max_conns: 10,

@@ -961,0 +983,0 @@ query_timeout_ms: 5e3

{
"name": "fauna",
"version": "0.7.0",
"version": "0.7.1",
"description": "A driver to query Fauna databases in browsers, Node.js, and other Javascript runtimes",

@@ -5,0 +5,0 @@ "homepage": "https://fauna.com",

@@ -42,3 +42,3 @@ import { ValueFormat } from "./wire-protocol";

* Time in milliseconds the client will keep an HTTP2 session open after all
* requests are completed. The default is 500 ms.
* requests are completed. The default is 5000 ms.
*/

@@ -45,0 +45,0 @@ http2_session_idle_ms: number;

@@ -42,3 +42,3 @@ import { ClientConfiguration, endpoints } from "./client-configuration";

format: "tagged",
http2_session_idle_ms: 500,
http2_session_idle_ms: 5000,
max_conns: 10,

@@ -45,0 +45,0 @@ query_timeout_ms: 5000,

@@ -29,6 +29,2 @@ /** following reference needed to include types for experimental fetch API in Node */

}: HTTPRequest): Promise<HTTPResponse> {
const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => controller.abort(), client_timeout_ms);
const response = await fetch(this.#url, {

@@ -38,3 +34,3 @@ method,

body: JSON.stringify(data),
signal,
signal: AbortSignal.timeout(client_timeout_ms),
}).catch((error) => {

@@ -41,0 +37,0 @@ throw new NetworkError("The network connection encountered a problem.", {

@@ -11,3 +11,3 @@ import { FetchClient } from "./fetch-client";

export const getDefaultHTTPClient = (options: HTTPClientOptions): HTTPClient =>
isNode() ? new NodeHTTP2Client(options) : new FetchClient(options);
isNode() ? NodeHTTP2Client.getClient(options) : new FetchClient(options);

@@ -14,0 +14,0 @@ export const isHTTPResponse = (res: any): res is HTTPResponse =>

@@ -26,8 +26,10 @@ let http2: any;

export class NodeHTTP2Client implements HTTPClient {
static #sessionMap: Map<string, SessionRC> = new Map();
static #clients: Map<string, NodeHTTP2Client> = new Map();
#http2_session_idle_ms: number;
#url: string;
#numberOfUsers = 0;
#session: ClientHttp2Session | null;
constructor({ http2_session_idle_ms, url }: HTTPClientOptions) {
private constructor({ http2_session_idle_ms, url }: HTTPClientOptions) {
if (http2 === undefined) {

@@ -39,92 +41,76 @@ throw new Error("Your platform does not support Node's http2 library");

this.#url = url;
this.#session = null;
}
/**
* Gets a {@link NodeHTTP2Client} matching the {@link HTTTPClientOptions}
* @param httpClientOptions - the {@link HTTTPClientOptions}
* @returns a {@link NodeHTTP2Client} matching the {@link HTTTPClientOptions}
*/
static getClient(httpClientOptions: HTTPClientOptions): NodeHTTP2Client {
const clientKey = NodeHTTP2Client.#getClientKey(httpClientOptions);
if (!NodeHTTP2Client.#clients.has(clientKey)) {
NodeHTTP2Client.#clients.set(
clientKey,
new NodeHTTP2Client(httpClientOptions)
);
}
// we know that we have a client here
const client = NodeHTTP2Client.#clients.get(clientKey) as NodeHTTP2Client;
client.#numberOfUsers++;
return client;
}
static #getClientKey({ http2_session_idle_ms, url }: HTTPClientOptions) {
return `${url}|${http2_session_idle_ms}`;
}
/** {@inheritDoc HTTPClient.request} */
async request({
client_timeout_ms,
data: requestData,
headers: requestHeaders,
method,
}: HTTPRequest): Promise<HTTPResponse> {
let req: ClientHttp2Stream;
const requestPromise = new Promise<HTTPResponse>(
(resolvePromise, rejectPromise) => {
const onResponse = (
http2ResponseHeaders: IncomingHttpHeaders & IncomingHttpStatusHeader
) => {
const status = Number(
http2ResponseHeaders[http2.constants.HTTP2_HEADER_STATUS]
async request(req: HTTPRequest): Promise<HTTPResponse> {
let retryCount = 0;
let memoizedError: any;
do {
try {
return await this.#doRequest(req);
} catch (error: any) {
// see https://github.com/nodejs/node/pull/42190/files
// and https://github.com/nodejs/help/issues/2105
//
// TLDR; In Node, there is a race condition between handling
// GOAWAY and submitting requests - that can cause
// clients that safely handle go away to submit
// requests after a GOAWAY was received anyway.
//
// technical explanation: node HTTP2 request gets put
// on event queue before it is actually executed. In the iterim,
// a GOAWAY can come and cause the request to fail
// with a GOAWAY.
if (error?.code !== "ERR_HTTP2_GOAWAY_SESSION") {
// TODO: be more discernable about error types
throw new NetworkError(
"The network connection encountered a problem.",
{
cause: error,
}
);
let responseData = "";
// append response data to the data string every time we receive new
// data chunks in the response
req.on("data", (chunk: any) => {
responseData += chunk;
});
// Once the response is finished, resolve the promise
req.on("end", () => {
resolvePromise({
status,
body: responseData,
headers: http2ResponseHeaders,
});
});
};
try {
const httpRequestHeaders: OutgoingHttpHeaders = {
...requestHeaders,
[http2.constants.HTTP2_HEADER_PATH]: "/query/1",
[http2.constants.HTTP2_HEADER_METHOD]: method,
};
const session = this.#connect();
req = session
.request(httpRequestHeaders)
.setEncoding("utf8")
.on("error", (error: any) => {
rejectPromise(error);
})
.on("response", onResponse);
req.write(JSON.stringify(requestData), "utf8");
// req.setTimeout must be called before req.end()
req.setTimeout(client_timeout_ms, () => {
req.destroy(new Error(`Client timeout`));
});
req.end();
} catch (error) {
rejectPromise(error);
}
memoizedError = error;
retryCount++;
}
);
try {
return await requestPromise;
} catch (error) {
// TODO: be more discernable about error types
throw new NetworkError("The network connection encountered a problem.", {
cause: error,
});
}
} while (retryCount < 3);
throw new NetworkError("The network connection encountered a problem.", {
cause: memoizedError,
});
}
/** {@inheritDoc HTTPClient.close} */
close() {
const session_rc = NodeHTTP2Client.#sessionMap.get(this.sessionKey);
if (!session_rc) return;
session_rc.refs.delete(this);
// if there are no clients referencing the session, then we can close it
if (session_rc.refs.size === 0) {
const session = session_rc.session;
if (session && !session.closed) session.close();
session_rc.session = null;
// defend against redundant close calls
if (this.isClosed()) {
return;
}
this.#numberOfUsers--;
if (this.#numberOfUsers === 0 && this.#session && !this.#session.closed) {
this.#session.close();
}
}

@@ -136,74 +122,90 @@

isClosed(): boolean {
const session_rc = NodeHTTP2Client.#sessionMap.get(this.sessionKey);
return (session_rc?.refs.size ?? 0) === 0;
return this.#numberOfUsers === 0;
}
/**
* Creates a key common the client that should share the same session
*/
get sessionKey() {
return `${this.#url}|${this.#http2_session_idle_ms}`;
}
#closeForAll() {
const session_rc = NodeHTTP2Client.#sessionMap.get(this.sessionKey);
if (!session_rc) return;
session_rc.refs.clear();
const session = session_rc.session;
if (session && !session.closed) session.close();
session_rc.session = null;
this.#numberOfUsers = 0;
if (this.#session && !this.#session.closed) {
this.#session.close();
}
}
#connect() {
let session_rc = NodeHTTP2Client.#sessionMap.get(this.sessionKey);
// initialize the Map if necessary
if (!session_rc) {
session_rc = {
session: null,
refs: new Set(),
};
NodeHTTP2Client.#sessionMap.set(this.sessionKey, session_rc);
}
// create a new session if necessary
if (session_rc.session === null || session_rc.session.closed) {
const http2_session_idle_ms = this.#http2_session_idle_ms;
const url = this.#url;
// create the session if it does not exist or is closed
if (!this.#session || this.#session.closed) {
const new_session: ClientHttp2Session = http2
.connect(url)
.connect(this.#url)
.once("error", () => this.#closeForAll())
.once("goaway", () => this.#closeForAll());
new_session.setTimeout(http2_session_idle_ms, () => {
new_session.setTimeout(this.#http2_session_idle_ms, () => {
this.#closeForAll();
});
session_rc.session = new_session;
this.#session = new_session;
}
return this.#session;
}
session_rc.refs.add(this);
#doRequest({
client_timeout_ms,
data: requestData,
headers: requestHeaders,
method,
}: HTTPRequest): Promise<HTTPResponse> {
return new Promise<HTTPResponse>((resolvePromise, rejectPromise) => {
let req: ClientHttp2Stream;
const onResponse = (
http2ResponseHeaders: IncomingHttpHeaders & IncomingHttpStatusHeader
) => {
const status = Number(
http2ResponseHeaders[http2.constants.HTTP2_HEADER_STATUS]
);
let responseData = "";
return session_rc.session;
// append response data to the data string every time we receive new
// data chunks in the response
req.on("data", (chunk: any) => {
responseData += chunk;
});
// Once the response is finished, resolve the promise
req.on("end", () => {
resolvePromise({
status,
body: responseData,
headers: http2ResponseHeaders,
});
});
};
try {
const httpRequestHeaders: OutgoingHttpHeaders = {
...requestHeaders,
[http2.constants.HTTP2_HEADER_PATH]: "/query/1",
[http2.constants.HTTP2_HEADER_METHOD]: method,
};
const session = this.#connect();
req = session
.request(httpRequestHeaders)
.setEncoding("utf8")
.on("error", (error: any) => {
rejectPromise(error);
})
.on("response", onResponse);
req.write(JSON.stringify(requestData), "utf8");
// req.setTimeout must be called before req.end()
req.setTimeout(client_timeout_ms, () => {
req.destroy(new Error(`Client timeout`));
});
req.end();
} catch (error) {
rejectPromise(error);
}
});
}
}
/**
* Wrapper to provide reference counting for sessions.
*
* @internal
*/
type SessionRC = {
/** A session to be shared among http clients */
session: ClientHttp2Session | null;
/**
* A Setof client references. We will only close the session when there are no
* references left. This cannot be a WeakSet, because WeakSets are not
* enumerable (can't check if they are empty).
*/
refs: Set<NodeHTTP2Client>;
};

@@ -179,2 +179,3 @@ import { ClientError } from "./errors";

}),
// es-lint-disable-next-line @typescript-eslint/no-unused-vars
set: (value: Page<QueryValue> | EmbeddedSet) => {

@@ -181,0 +182,0 @@ throw new ClientError(

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc