firebase
Version:
Firebase JavaScript library for web and Node.js
4 lines (2 loc) • 29 kB
JavaScript
import{_removeServiceInstance as t,getApp as e,_getProvider,_registerComponent as s,registerVersion as r,_isFirebaseServerApp as i,SDK_VERSION as n}from"https://www.gstatic.com/firebasejs/12.11.0/firebase-app.js";class FirebaseError extends Error{constructor(t,e,s){super(e),this.code=t,this.customData=s,this.name="FirebaseError",Object.setPrototypeOf(this,FirebaseError.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,ErrorFactory.prototype.create)}}class ErrorFactory{constructor(t,e,s){this.service=t,this.serviceName=e,this.errors=s}create(t,...e){const s=e[0]||{},r=`${this.service}/${t}`,i=this.errors[t],n=i?function replaceTemplate(t,e){return t.replace(a,((t,s)=>{const r=e[s];return null!=r?String(r):`<${s}?>`}))}(i,s):"Error",o=`${this.serviceName}: ${n} (${r}).`;return new FirebaseError(r,o,s)}}const a=/\{\$([^}]+)}/g;function isCloudWorkstation(t){try{return(t.startsWith("http://")||t.startsWith("https://")?new URL(t).hostname:t).endsWith(".cloudworkstations.dev")}catch{return!1}}class Component{constructor(t,e,s){this.name=t,this.instanceFactory=e,this.type=s,this.multipleInstances=!1,this.serviceProps={},this.instantiationMode="LAZY",this.onInstanceCreated=null}setInstantiationMode(t){return this.instantiationMode=t,this}setMultipleInstances(t){return this.multipleInstances=t,this}setServiceProps(t){return this.serviceProps=t,this}setInstanceCreatedCallback(t){return this.onInstanceCreated=t,this}}var o;!function(t){t[t.DEBUG=0]="DEBUG",t[t.VERBOSE=1]="VERBOSE",t[t.INFO=2]="INFO",t[t.WARN=3]="WARN",t[t.ERROR=4]="ERROR",t[t.SILENT=5]="SILENT"}(o||(o={}));const c={debug:o.DEBUG,verbose:o.VERBOSE,info:o.INFO,warn:o.WARN,error:o.ERROR,silent:o.SILENT},h=o.INFO,l={[o.DEBUG]:"log",[o.VERBOSE]:"log",[o.INFO]:"info",[o.WARN]:"warn",[o.ERROR]:"error"},defaultLogHandler=(t,e,...s)=>{if(e<t.logLevel)return;const r=(new Date).toISOString(),i=l[e];if(!i)throw new Error(`Attempted to log a message with an invalid logType (value: ${e})`);console[i](`[${r}] ${t.name}:`,...s)};const u="@firebase/data-connect",d="0.5.0";let p="";const g={OTHER:"other",ALREADY_INITIALIZED:"already-initialized",NOT_INITIALIZED:"not-initialized",NOT_SUPPORTED:"not-supported",INVALID_ARGUMENT:"invalid-argument",PARTIAL_ERROR:"partial-error",UNAUTHORIZED:"unauthorized"};class DataConnectError extends FirebaseError{constructor(t,e){super(t,e),this.name="DataConnectError",Object.setPrototypeOf(this,DataConnectError.prototype)}toString(){return`${this.name}[code=${this.code}]: ${this.message}`}}class DataConnectOperationError extends DataConnectError{constructor(t,e){super(g.PARTIAL_ERROR,t),this.name="DataConnectOperationError",this.response=e}}class EntityDataObject{getServerValue(t){return this.serverValues[t]}constructor(t){this.globalID=t,this.serverValues={},this.referencedFrom=new Set}getServerValues(){return this.serverValues}toJSON(){return{globalID:this.globalID,map:this.serverValues,referencedFrom:Array.from(this.referencedFrom)}}static fromJSON(t){const e=new EntityDataObject(t.globalID);return e.serverValues=t.map,e.referencedFrom=new Set(t.referencedFrom),e}updateServerValue(t,e,s){return this.serverValues[t]=e,this.referencedFrom.add(s),Array.from(this.referencedFrom)}}class InMemoryCacheProvider{constructor(t){this._keyId=t,this.edos=new Map,this.resultTrees=new Map}async setResultTree(t,e){this.resultTrees.set(t,e)}async getResultTree(t){return this.resultTrees.get(t)}async updateEntityData(t){this.edos.set(t.globalID,t)}async getEntityData(t){return this.edos.has(t)||this.edos.set(t,new EntityDataObject(t)),this.edos.get(t)}close(){return Promise.resolve()}}const f="_id";class EntityNode{constructor(){this.scalars={},this.references={},this.objectLists={},this.entityDataKeys=new Set}async loadData(t,e,s,r,i){if(void 0!==e){if("object"!=typeof e||Array.isArray(e))throw new DataConnectError(g.INVALID_ARGUMENT,"EntityNode initialized with non-object value");if(null!==e){"object"==typeof e&&s&&s[f]&&"string"==typeof s[f]&&(this.globalId=s[f],this.entityData=await i.getEntityData(this.globalId));for(const n in e)if(e.hasOwnProperty(n))if("object"==typeof e[n])if(Array.isArray(e[n])){const a=s&&s[n],o=[],c=[];for(const[s,h]of e[n].entries())if("object"==typeof h)if(Array.isArray(h));else{const e=new EntityNode;await e.loadData(t,h,a&&a[s],r,i),o.push(e)}else c.push(h);if(c.length>0&&o.length>0)this.scalars[n]=e[n];else if(c.length>0)if(this.entityData){const e=this.entityData.updateServerValue(n,c,t);this.entityDataKeys.add(n),r.add(e)}else this.scalars[n]=c;else o.length>0?this.objectLists[n]=o:this.scalars[n]=[]}else{if(null===e[n]){this.scalars[n]=null;continue}const a=new EntityNode;await a.loadData(t,e[n],s&&s[n],r,i),this.references[n]=a}else if(this.entityData){const s=this.entityData.updateServerValue(n,e[n],t);this.entityDataKeys.add(n),r.add(s)}else this.scalars[n]=e[n];this.entityData&&await i.updateEntityData(this.entityData)}}}toJSON(t){const e={};if(t===y.hydrated){if(this.entityData)for(const t of this.entityDataKeys)e[t]=this.entityData.getServerValue(t);if(this.scalars&&Object.assign(e,this.scalars),this.references)for(const s in this.references)this.references.hasOwnProperty(s)&&(e[s]=this.references[s].toJSON(t));if(this.objectLists)for(const s in this.objectLists)this.objectLists.hasOwnProperty(s)&&(e[s]=this.objectLists[s].map((e=>e.toJSON(t))));return e}if(this.entityData&&(e[f]=this.entityData.globalID),e._entity_data_keys=Array.from(this.entityDataKeys),this.scalars&&(e._scalars=this.scalars),this.references){const s={};for(const e in this.references)this.references.hasOwnProperty(e)&&(s[e]=this.references[e].toJSON(t));e._references=s}if(this.objectLists){const s={};for(const e in this.objectLists)this.objectLists.hasOwnProperty(e)&&(s[e]=this.objectLists[e].map((e=>e.toJSON(t))));e._objectLists=s}return e}static fromJson(t){const e=new EntityNode;if(t.backingData&&(e.entityData=EntityDataObject.fromJSON(t.backingData)),e.globalId=t.globalID,e.scalars=t.scalars,t.references){const s={};for(const e in t.references)t.references.hasOwnProperty(e)&&(s[e]=EntityNode.fromJson(t.references[e]));e.references=s}if(t.objectLists){const s={};for(const e in t.objectLists)t.objectLists.hasOwnProperty(e)&&(s[e]=t.objectLists[e].map((t=>EntityNode.fromJson(t))));e.objectLists=s}return e}}var y;!function(t){t[t.hydrated=0]="hydrated",t[t.dehydrated=1]="dehydrated"}(y||(y={}));class ResultTree{static fromJson(t){return new ResultTree(EntityNode.fromJson(t.rootStub),t.maxAge,t.cachedAt,t.lastAccessed)}constructor(t,e=0,s,r){this.rootStub=t,this.maxAge=e,this.cachedAt=s,this._lastAccessed=r}isStale(){return Date.now()-new Date(this.cachedAt.getTime()).getTime()>1e3*this.maxAge}updateMaxAge(t){this.maxAge=t}updateAccessed(){this._lastAccessed=new Date}get lastAccessed(){return this._lastAccessed}getRootStub(){return this.rootStub}}class ImpactedQueryRefsAccumulator{constructor(t){this.queryId=t,this.impacted=new Set}add(t){t.filter((t=>t!==this.queryId)).forEach((t=>this.impacted.add(t)))}consumeEvents(){const t=Array.from(this.impacted);return this.impacted.clear(),t}}class ResultTreeProcessor{hydrateResults(t){return t.toJSON(y.hydrated)}async dehydrateResults(t,e,s,r){const i=new ImpactedQueryRefsAccumulator(r),n=new EntityNode;return await n.loadData(r,t,e,i,s),{entityNode:n,impacted:i.consumeEvents()}}}class DataConnectCache{constructor(t,e,s,r,i){this.authProvider=t,this.projectId=e,this.connectorConfig=s,this.host=r,this.cacheSettings=i,this.cacheProvider=null,this.uid=null,this.authProvider.addTokenChangeListener((async t=>{const e=this.authProvider.getAuth().getUid();if(this.uid!==e){this.cacheProvider?.close(),this.uid=e;const t=await this.getIdentifier(this.uid);this.cacheProvider=this.initializeNewProviders(t)}}))}async initialize(){if(!this.cacheProvider){const t=await this.getIdentifier(this.uid);this.cacheProvider=this.initializeNewProviders(t)}}async getIdentifier(t){const e=`memory-${this.projectId}-${this.connectorConfig.service}-${this.connectorConfig.connector}-${this.connectorConfig.location}-${t}-${this.host}`;return await async function generateSHA256Hash(t){const e=(new TextEncoder).encode(t),s=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(s)).map((t=>t.toString(16).padStart(2,"0"))).join("")}(e)}initializeNewProviders(t){return this.cacheSettings.cacheProvider.initialize(t)}async containsResultTree(t){await this.initialize();return void 0!==await this.cacheProvider.getResultTree(t)}async getResultTree(t){return await this.initialize(),this.cacheProvider.getResultTree(t)}async getResultJSON(t){await this.initialize();const e=new ResultTreeProcessor,s=this.cacheProvider,r=await s.getResultTree(t);if(!r)throw new DataConnectError(g.INVALID_ARGUMENT,`${t} not found in cache. Call "update()" first.`);return e.hydrateResults(r.getRootStub())}async update(t,e,s){await this.initialize();const r=new ResultTreeProcessor,i=this.cacheProvider,{entityNode:n,impacted:a}=await r.dehydrateResults(e,s,i,t),o=new Date;return await i.setResultTree(t,new ResultTree(n,e.maxAge||this.cacheSettings.maxAgeSeconds,o,o)),a}}class MemoryStub{constructor(){this.type="MEMORY"}initialize(t){return new InMemoryCacheProvider(t)}}class AppCheckTokenProvider{constructor(t,e){this.appCheckProvider=e,i(t)&&t.settings.appCheckToken&&(this.serverAppAppCheckToken=t.settings.appCheckToken),this.appCheck=e?.getImmediate({optional:!0}),this.appCheck||e?.get().then((t=>this.appCheck=t)).catch()}getToken(){return this.serverAppAppCheckToken?Promise.resolve({token:this.serverAppAppCheckToken}):this.appCheck?this.appCheck.getToken():new Promise(((t,e)=>{setTimeout((()=>{this.appCheck?this.getToken().then(t,e):t(null)}),0)}))}addTokenChangeListener(t){this.appCheckProvider?.get().then((e=>e.addTokenListener(t)))}}const m=new class Logger{constructor(t){this.name=t,this._logLevel=h,this._logHandler=defaultLogHandler,this._userLogHandler=null}get logLevel(){return this._logLevel}set logLevel(t){if(!(t in o))throw new TypeError(`Invalid value "${t}" assigned to \`logLevel\``);this._logLevel=t}setLogLevel(t){this._logLevel="string"==typeof t?c[t]:t}get logHandler(){return this._logHandler}set logHandler(t){if("function"!=typeof t)throw new TypeError("Value assigned to `logHandler` must be a function");this._logHandler=t}get userLogHandler(){return this._userLogHandler}set userLogHandler(t){this._userLogHandler=t}debug(...t){this._userLogHandler&&this._userLogHandler(this,o.DEBUG,...t),this._logHandler(this,o.DEBUG,...t)}log(...t){this._userLogHandler&&this._userLogHandler(this,o.VERBOSE,...t),this._logHandler(this,o.VERBOSE,...t)}info(...t){this._userLogHandler&&this._userLogHandler(this,o.INFO,...t),this._logHandler(this,o.INFO,...t)}warn(...t){this._userLogHandler&&this._userLogHandler(this,o.WARN,...t),this._logHandler(this,o.WARN,...t)}error(...t){this._userLogHandler&&this._userLogHandler(this,o.ERROR,...t),this._logHandler(this,o.ERROR,...t)}}("@firebase/data-connect");function setLogLevel(t){m.setLogLevel(t)}function logDebug(t){m.debug(`DataConnect (${p}): ${t}`)}function logError(t){m.error(`DataConnect (${p}): ${t}`)}class FirebaseAuthProvider{constructor(t,e,s){this._appName=t,this._options=e,this._authProvider=s,this._auth=s.getImmediate({optional:!0}),this._auth||s.onInit((t=>this._auth=t))}getAuth(){return this._auth}getToken(t){return this._auth?this._auth.getToken(t).catch((t=>t&&"auth/token-not-initialized"===t.code?(logDebug("Got auth/token-not-initialized error. Treating as null token."),null):(logError("Error received when attempting to retrieve token: "+JSON.stringify(t)),Promise.reject(t)))):new Promise(((e,s)=>{setTimeout((()=>{this._auth?this.getToken(t).then(e,s):e(null)}),0)}))}addTokenChangeListener(t){this._auth?.addAuthTokenListener(t)}removeTokenChangeListener(t){this._authProvider.get().then((e=>e.removeAuthTokenListener(t))).catch((t=>logError(t)))}}const b="query",E="mutation",_="SERVER",C="CACHE";function populatePath(t,e,s){let r=e;for(const e of t)"object"!=typeof r[e]&&(r[e]={}),r=r[e];if("entityId"in s&&s.entityId)r._id=s.entityId;else if("entityIds"in s){const t=s.entityIds;for(let e=0;e<t.length;e++){const s=t[e];void 0===r[e]&&(r[e]={}),r[e]._id=s}}}let v,T;function sortKeysForObj(t){return Object.keys(t).sort().reduce(((e,s)=>(e[s]=t[s],e)),{})}function getRefSerializer(t,e,s,r){return function toJSON(){return{data:e,refInfo:{name:t.name,variables:t.variables,connectorConfig:{projectId:t.dataConnect.app.options.projectId,...t.dataConnect.getSettings()}},fetchTime:r,source:s}}}!function setEncoder(t){v=t}((t=>JSON.stringify(sortKeysForObj(t)))),function setDecoder(t){T=t}((t=>sortKeysForObj(JSON.parse(t))));class QueryManager{async preferCacheResults(t,e=!1){let s;try{s=await this.fetchCacheResults(t,e)}catch(t){}return s||this.fetchServerResults(t)}constructor(t,e,s){this.transport=t,this.dc=e,this.cache=s,this.callbacks=new Map,this.subscriptionCache=new Map,this.queue=[]}async waitForQueuedWrites(){for(const t of this.queue)await t;this.queue=[]}updateSSR(t){this.queue.push(this.updateCache(t).then((async e=>this.publishCacheResultsToSubscribers(e,t.fetchTime))))}async updateCache(t,e){if(await this.waitForQueuedWrites(),this.cache){const s=function parseEntityIds(t){const e=t.extensions?.dataConnect,s=Object.assign(t);if(!e)return s;const r={};for(const t of e){const{path:e}=t;populatePath(e,r,t)}return r}(t),r=function getMaxAgeFromExtensions(t){if(!t)return;for(const e of t)if("maxAge"in e&&void 0!==e.maxAge&&null!==e.maxAge&&e.maxAge.endsWith("s"))return Number(e.maxAge.substring(0,e.maxAge.length-1))}(e);return void 0!==r&&(this.cache.cacheSettings.maxAgeSeconds=r),this.cache.update(v({name:t.ref.name,variables:t.ref.variables,refType:b}),t.data,s)}{const e=v({name:t.ref.name,variables:t.ref.variables,refType:b});return this.subscriptionCache.set(e,t),[e]}}addSubscription(t,e,s,r,i){const n=v({name:t.name,variables:t.variables,refType:b}),unsubscribe=()=>{if(this.callbacks.has(n)){const t=this.callbacks.get(n);this.callbacks.set(n,t.filter((t=>t!==a))),s?.()}},a={userCallback:e,errCallback:r,unsubscribe:unsubscribe};i&&this.updateSSR(i);return this.preferCacheResults(t,!0).then(void 0,(t=>{})),this.callbacks.has(n)||this.callbacks.set(n,[]),this.callbacks.get(n).push(a),unsubscribe}async fetchServerResults(t){await this.waitForQueuedWrites();const e=v({name:t.name,variables:t.variables,refType:b});try{const r=await this.transport.invokeQuery(t.name,t.variables),i=Date.now().toString(),n=r.extensions,a={...r,ref:t,source:_,fetchTime:i,data:r.data,extensions:(s=n,{dataConnect:s.dataConnect?.filter((t=>"entityId"in t||"entityIds"in t))}),toJSON:getRefSerializer(t,r.data,_,i)};let o=[];return o=await this.updateCache(a,n?.dataConnect),this.publishDataToSubscribers(e,a),this.cache?await this.publishCacheResultsToSubscribers(o,i):this.subscriptionCache.set(e,a),a}catch(t){throw this.publishErrorToSubscribers(e,t),t}var s}async fetchCacheResults(t,e=!1){let s;if(await this.waitForQueuedWrites(),s=this.cache?await this.getFromResultTreeCache(t,e):await this.getFromSubscriberCache(t),!s)throw new DataConnectError(g.OTHER,"No cache entry found for query: "+t.name);const r=Date.now().toString(),i={...s,ref:t,source:C,fetchTime:r,data:s.data,extensions:s.extensions,toJSON:getRefSerializer(t,s.data,C,r)};if(this.cache){const e=v({name:t.name,variables:t.variables,refType:b});await this.publishCacheResultsToSubscribers([e],r)}else{const e=v({name:t.name,variables:t.variables,refType:b});this.subscriptionCache.set(e,i),this.publishDataToSubscribers(e,i)}return i}publishErrorToSubscribers(t,e){this.callbacks.get(t)?.forEach((t=>{t.errCallback&&t.errCallback(e)}))}async getFromResultTreeCache(t,e=!1){const s=v({name:t.name,variables:t.variables,refType:b});if(!this.cache||!await this.cache.containsResultTree(s))return null;const r=await this.cache.getResultJSON(s),i=await this.cache.getResultTree(s);if(!e&&i.isStale())return null;const n={source:C,ref:t,data:r,toJSON:getRefSerializer(t,r,C,i.cachedAt.toString()),fetchTime:i.cachedAt.toString()};return(await this.cache.getResultTree(s)).updateAccessed(),n}async getFromSubscriberCache(t){const e=v({name:t.name,variables:t.variables,refType:b});if(!this.subscriptionCache.has(e))return;const s=this.subscriptionCache.get(e);return s.source=C,s.toJSON=getRefSerializer(s.ref,s.data,C,s.fetchTime),s}publishDataToSubscribers(t,e){if(!this.callbacks.has(t))return;this.callbacks.get(t).forEach((t=>{t.userCallback(e)}))}async publishCacheResultsToSubscribers(t,e){if(this.cache)for(const s of t){if(!this.callbacks.get(s))continue;const t=(await this.cache.getResultTree(s)).getRootStub().toJSON(y.hydrated),{name:r,variables:i}=T(s),n={dataConnect:this.dc,refType:b,name:r,variables:i};this.publishDataToSubscribers(s,{data:t,fetchTime:e,ref:n,source:C,toJSON:getRefSerializer(n,t,C,e)})}}enableEmulator(t,e){this.transport.useEmulator(t,e)}}const w={Base:"Base",Generated:"Generated",TanstackReactCore:"TanstackReactCore",GeneratedReact:"GeneratedReact",TanstackAngularCore:"TanstackAngularCore",GeneratedAngular:"GeneratedAngular"},R="firebasedataconnect.googleapis.com";function addToken(t,e){if(!e)return t;const s=new URL(t);return s.searchParams.append("key",e),s.toString()}let S=globalThis.fetch;function getGoogApiClientValue(t,e){let s="gl-js/ fire/"+p;return e!==w.Base&&e!==w.Generated?s+=" js/"+e.toLowerCase():(t||e===w.Generated)&&(s+=" js/gen"),s}async function dcFetch(t,e,{signal:s},r,i,n,a,o,c){if(!S)throw new DataConnectError(g.OTHER,"No Fetch Implementation detected!");const h={"Content-Type":"application/json","X-Goog-Api-Client":getGoogApiClientValue(a,o)};i&&(h["X-Firebase-Auth-Token"]=i),r&&(h["x-firebase-gmpid"]=r),n&&(h["X-Firebase-AppCheck"]=n);const l={body:JSON.stringify(e),method:"POST",headers:h,signal:s};let u,d;isCloudWorkstation(t)&&c&&(l.credentials="include");try{u=await S(t,l)}catch(t){throw new DataConnectError(g.OTHER,"Failed to fetch: "+JSON.stringify(t))}try{d=await u.json()}catch(t){throw new DataConnectError(g.OTHER,JSON.stringify(t))}const p=function getErrorMessage(t){if("message"in t&&t.message)return t.message;return JSON.stringify(t)}(d);if(u.status>=400){if(logError("Error while performing request: "+JSON.stringify(d)),401===u.status)throw new DataConnectError(g.UNAUTHORIZED,p);throw new DataConnectError(g.OTHER,p)}if(d.errors&&d.errors.length){const t=JSON.stringify(d.errors),e={errors:d.errors,data:d.data};throw new DataConnectOperationError("DataConnect error while performing request: "+t,e)}return d.extensions||(d.extensions={dataConnect:[]}),d}class RESTTransport{constructor(t,e,s,r,i,n,a=!1,o=w.Base){this.apiKey=e,this.appId=s,this.authProvider=r,this.appCheckProvider=i,this._isUsingGen=a,this._callerSdkType=o,this._host="",this._location="l",this._connectorName="",this._secure=!0,this._project="p",this._accessToken=null,this._appCheckToken=null,this._lastToken=null,this._isUsingEmulator=!1,this.invokeQuery=(t,e)=>{const s=new AbortController;return this.withRetry((()=>dcFetch(addToken(`${this.endpointUrl}:executeQuery`,this.apiKey),{name:`projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,operationName:t,variables:e},s,this.appId,this._accessToken,this._appCheckToken,this._isUsingGen,this._callerSdkType,this._isUsingEmulator)))},this.invokeMutation=(t,e)=>{const s=new AbortController;return this.withRetry((()=>dcFetch(addToken(`${this.endpointUrl}:executeMutation`,this.apiKey),{name:`projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,operationName:t,variables:e},s,this.appId,this._accessToken,this._appCheckToken,this._isUsingGen,this._callerSdkType,this._isUsingEmulator)))},n&&("number"==typeof n.port&&(this._port=n.port),void 0!==n.sslEnabled&&(this._secure=n.sslEnabled),this._host=n.host);const{location:c,projectId:h,connector:l,service:u}=t;if(c&&(this._location=c),h&&(this._project=h),this._serviceName=u,!l)throw new DataConnectError(g.INVALID_ARGUMENT,"Connector Name required!");this._connectorName=l,this.authProvider?.addTokenChangeListener((t=>{logDebug(`New Token Available: ${t}`),this._accessToken=t})),this.appCheckProvider?.addTokenChangeListener((t=>{const{token:e}=t;logDebug(`New App Check Token Available: ${e}`),this._appCheckToken=e}))}get endpointUrl(){return function urlBuilder(t,e){const{connector:s,location:r,projectId:i,service:n}=t,{host:a,sslEnabled:o,port:c}=e;let h=`${o?"https":"http"}://${a||R}`;if("number"==typeof c)h+=`:${c}`;else if(void 0!==c)throw logError("Port type is of an invalid type"),new DataConnectError(g.INVALID_ARGUMENT,"Incorrect type for port passed in!");return`${h}/v1/projects/${i}/locations/${r}/services/${n}/connectors/${s}`}({connector:this._connectorName,location:this._location,projectId:this._project,service:this._serviceName},{host:this._host,sslEnabled:this._secure,port:this._port})}useEmulator(t,e,s){this._host=t,this._isUsingEmulator=!0,"number"==typeof e&&(this._port=e),void 0!==s&&(this._secure=s)}onTokenChanged(t){this._accessToken=t}async getWithAuth(t=!1){let e=new Promise((t=>t(this._accessToken)));if(this.appCheckProvider){const t=await this.appCheckProvider.getToken();t&&(this._appCheckToken=t.token)}return e=this.authProvider?this.authProvider.getToken(t).then((t=>t?(this._accessToken=t.accessToken,this._accessToken):null)):new Promise((t=>t(""))),e}_setLastToken(t){this._lastToken=t}withRetry(t,e=!1){let s=!1;return this.getWithAuth(e).then((t=>(s=this._lastToken!==t,this._lastToken=t,t))).then(t).catch((r=>{if("code"in r&&r.code===g.UNAUTHORIZED&&!e&&s)return logDebug("Retrying due to unauthorized"),this.withRetry(t,!0);throw r}))}_setCallerSdkType(t){this._callerSdkType=t}}function mutationRef(t,e,s){t.setInitialized();return{dataConnect:t,name:e,refType:E,variables:s}}class MutationManager{constructor(t){this._transport=t,this._inflight=[]}executeMutation(t){const e=this._transport.invokeMutation(t.name,t.variables),s=e.then((e=>({...e,source:_,ref:t,fetchTime:Date.now().toLocaleString()})));this._inflight.push(e);const removePromise=()=>this._inflight=this._inflight.filter((t=>t!==e));return e.then(removePromise,removePromise),s}}function executeMutation(t){return t.dataConnect._mutationManager.executeMutation(t)}function parseOptions(t){const[e,s]=t.split("://"),r="https"===e,[i,n]=s.split(":");return{host:i,port:Number(n),sslEnabled:r}}class DataConnect{constructor(t,e,s,r){if(this.app=t,this.dataConnectOptions=e,this._authProvider=s,this._appCheckProvider=r,this.isEmulator=!1,this._initialized=!1,this._isUsingGeneratedSdk=!1,this._callerSdkType=w.Base,"undefined"!=typeof process&&process.env){const t=process.env.FIREBASE_DATA_CONNECT_EMULATOR_HOST;t&&(logDebug("Found custom host. Using emulator"),this.isEmulator=!0,this._transportOptions=parseOptions(t))}}getCache(){return this.cache}_useGeneratedSdk(){this._isUsingGeneratedSdk||(this._isUsingGeneratedSdk=!0)}_setCallerSdkType(t){this._callerSdkType=t,this._initialized&&this._transport._setCallerSdkType(t)}_delete(){return t(this.app,"data-connect",JSON.stringify(this.getSettings())),Promise.resolve()}getSettings(){const t=JSON.parse(JSON.stringify(this.dataConnectOptions));return delete t.projectId,t}setCacheSettings(t){this._cacheSettings=t}setInitialized(){if(this._initialized)return;void 0===this._transportClass&&(logDebug("transportClass not provided. Defaulting to RESTTransport."),this._transportClass=RESTTransport),this._authTokenProvider=new FirebaseAuthProvider(this.app.name,this.app.options,this._authProvider);const t={connector:this.dataConnectOptions.connector,service:this.dataConnectOptions.service,location:this.dataConnectOptions.location};this._cacheSettings&&(this.cache=new DataConnectCache(this._authTokenProvider,this.app.options.projectId,t,this._transportOptions?.host||R,this._cacheSettings)),this._appCheckProvider&&(this._appCheckTokenProvider=new AppCheckTokenProvider(this.app,this._appCheckProvider)),this._transport=new this._transportClass(this.dataConnectOptions,this.app.options.apiKey,this.app.options.appId,this._authTokenProvider,this._appCheckTokenProvider,void 0,this._isUsingGeneratedSdk,this._callerSdkType),this._transportOptions&&this._transport.useEmulator(this._transportOptions.host,this._transportOptions.port,this._transportOptions.sslEnabled),this._queryManager=new QueryManager(this._transport,this,this.cache),this._mutationManager=new MutationManager(this._transport),this._initialized=!0}enableEmulator(t){if(this._transportOptions&&this._initialized&&!areTransportOptionsEqual(this._transportOptions,t))throw logError("enableEmulator called after initialization"),new DataConnectError(g.ALREADY_INITIALIZED,"DataConnect instance already initialized!");this._transportOptions=t,this.isEmulator=!0}}function areTransportOptionsEqual(t,e){return t.host===e.host&&t.port===e.port&&t.sslEnabled===e.sslEnabled}function connectDataConnectEmulator(t,e,s,r=!1){isCloudWorkstation(e)&&async function pingServer(t){return(await fetch(t,{credentials:"include"})).ok}(`https://${e}${s?`:${s}`:""}`),t.enableEmulator({host:e,port:s,sslEnabled:r})}function getDataConnect(t,s,r){let i,n,a;"location"in t?(n=t,i=e(),a=s):(i=t,n=s,a=r),i&&0!==Object.keys(i).length||(i=e());const o={...n,projectId:i.options.projectId},c=Object.fromEntries(Object.entries(o).sort()),h=_getProvider(i,"data-connect"),l=JSON.stringify(c);if(h.isInitialized(l)){const t=h.getImmediate({identifier:l}),e=h.getOptions(l);if(Object.keys(e).length>0)return logDebug("Re-using cached instance"),t}validateDCOptions(n),logDebug("Creating new DataConnect instance");const u=h.initialize({instanceIdentifier:l,options:Object.fromEntries(Object.entries({...c}).sort())});return a?.cacheSettings&&u.setCacheSettings(a.cacheSettings),u}function validateDCOptions(t){if(!t)throw new DataConnectError(g.INVALID_ARGUMENT,"DC Option Required");return["connector","location","service"].forEach((e=>{if(null===t[e]||void 0===t[e])throw new DataConnectError(g.INVALID_ARGUMENT,`${e} Required`)})),!0}function terminate(t){return t._delete()}const k={MEMORY:"MEMORY"};function makeMemoryCacheProvider(){return new MemoryStub}const D={PREFER_CACHE:"PREFER_CACHE",CACHE_ONLY:"CACHE_ONLY",SERVER_ONLY:"SERVER_ONLY"};function executeQuery(t,e){if(t.refType!==b)return Promise.reject(new DataConnectError(g.INVALID_ARGUMENT,"ExecuteQuery can only execute query operations"));const s=t.dataConnect._queryManager,r=e?.fetchPolicy??D.PREFER_CACHE;switch(r){case D.SERVER_ONLY:return s.fetchServerResults(t);case D.CACHE_ONLY:return s.fetchCacheResults(t,!0);case D.PREFER_CACHE:return s.preferCacheResults(t,!1);default:throw new DataConnectError(g.INVALID_ARGUMENT,`Invalid fetch policy: ${r}`)}}function queryRef(t,e,s,r){return t.setInitialized(),void 0!==r&&t._queryManager.updateSSR(r),{dataConnect:t,refType:b,name:e,variables:s}}function toQueryRef(t){const{refInfo:{name:e,variables:s,connectorConfig:r}}=t;return queryRef(getDataConnect(r),e,s)}function validateArgs(t,e,s,r){let i,n;if(e&&"enableEmulator"in e?(i=e,n=s):(i=getDataConnect(t),n=e),!i||!n&&r)throw new DataConnectError(g.INVALID_ARGUMENT,"Variables required.");return{dc:i,vars:n}}function validateArgsWithOptions(t,e,s,r,i,n){let a,o,c;if(e&&"enableEmulator"in e?(a=e,i?(o=s,c=r):(o=void 0,c=s)):(a=getDataConnect(t),i?(o=e,c=s):(o=void 0,c=e)),!a||!o&&n)throw new DataConnectError(g.INVALID_ARGUMENT,"Variables required.");return{dc:a,vars:o,options:c}}function subscribe(t,e,s,r){let i,n,a;if("refInfo"in t){const e=t,{data:s,source:r,fetchTime:a}=e;i=toQueryRef(e),n={data:s,source:r,fetchTime:a,ref:i,toJSON:getRefSerializer(i,s,r,a)}}else i=t;if("function"==typeof e?a=e:(a=e.onNext,s=e.onErr,r=e.onComplete),!a)throw new DataConnectError(g.INVALID_ARGUMENT,"Must provide onNext");return i.dataConnect._queryManager.addSubscription(i,a,r,s,n)}!function registerDataConnect(t){!function setSDKVersion(t){p=t}(n),s(new Component("data-connect",((t,{instanceIdentifier:e,options:s})=>{const r=t.getProvider("app").getImmediate(),i=t.getProvider("auth-internal"),n=t.getProvider("app-check-internal");let a=s;if(e&&(a={...JSON.parse(e),...a}),!r.options.projectId)throw new DataConnectError(g.INVALID_ARGUMENT,"Project ID must be provided. Did you pass in a proper projectId to initializeApp?");return new DataConnect(r,{...a,projectId:r.options.projectId},i,n)}),"PUBLIC").setMultipleInstances(!0)),r(u,d,t),r(u,d,"esm2020")}();export{w as CallerSdkTypeEnum,g as Code,DataConnect,DataConnectError,DataConnectOperationError,E as MUTATION_STR,MutationManager,b as QUERY_STR,D as QueryFetchPolicy,C as SOURCE_CACHE,_ as SOURCE_SERVER,k as StorageType,areTransportOptionsEqual,connectDataConnectEmulator,executeMutation,executeQuery,getDataConnect,makeMemoryCacheProvider,mutationRef,parseOptions,queryRef,setLogLevel,subscribe,terminate,toQueryRef,validateArgs,validateArgsWithOptions,validateDCOptions};
//# sourceMappingURL=firebase-data-connect.js.map