@pushmesh/sdk 0.7.3-rc.3 → 0.7.3-rc.4
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/dist/cjs/perfil.d.ts +1 -1
- package/dist/cjs/perfil.js +1 -1
- package/dist/cjs/permissions.js +1 -1
- package/dist/cjs/queue.js +1 -1
- package/package.json +1 -1
package/dist/cjs/perfil.d.ts
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* linha sozinho (script `version` → scripts/sync-versao.mjs); editando à mão,
|
|
21
21
|
* suba as duas.
|
|
22
22
|
*/
|
|
23
|
-
export declare const SDK_VERSAO = "0.7.3-rc.
|
|
23
|
+
export declare const SDK_VERSAO = "0.7.3-rc.4";
|
|
24
24
|
export interface PerfilDispositivo {
|
|
25
25
|
device_os?: string;
|
|
26
26
|
fabricante?: string;
|
package/dist/cjs/perfil.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true}),exports.SDK_VERSAO=void 0,exports.coletarPerfil=coletarPerfil;const react_native_1=require("react-native"),storage_1=require("./storage");function moduloPerfil(){const mods=react_native_1.NativeModules;return"ios"===react_native_1.Platform.OS?mods.PushMeshApns:mods.PushMeshFirebase}function timezoneId(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||void 0}catch{return}}function pais(){try{const loc=Intl.DateTimeFormat().resolvedOptions().locale,m=/[-_]([A-Za-z]{2})(?:[-_]|$)/.exec(loc);return m?m[1].toUpperCase():void 0}catch{return}}async function proximaSessao(){const atual=Number(await(0,storage_1.getItem)(storage_1.KEYS.sessoes)??"0"),proxima=Number.isFinite(atual)&&atual>=0?atual+1:1;return await(0,storage_1.setItem)(storage_1.KEYS.sessoes,String(proxima)),proxima}function semVazios(p){const out={};for(const[k,v]of Object.entries(p))null!=v&&""!==v&&(out[k]=v);return out}async function coletarPerfil(){const perfil={sdk_versao:exports.SDK_VERSAO,timezone_id:timezoneId(),pais:pais()};try{perfil.sessoes=await proximaSessao()}catch{}try{const nativo=moduloPerfil();if(nativo?.perfilDispositivo){const n=await nativo.perfilDispositivo();Object.assign(perfil,{device_os:n.device_os,fabricante:n.fabricante,modelo:n.modelo,net_type:n.net_type,carrier:n.carrier,rooted:n.rooted,standby_bucket:n.standby_bucket,bateria_irrestrita:n.bateria_irrestrita,notif_permissoes:n.notif_permissoes,instalacao_id:n.instalacao_id})}}catch{}if(!perfil.device_os){const v=react_native_1.Platform.Version;perfil.device_os="string"==typeof v?v:String(v)}if(!perfil.fabricante){const c=react_native_1.Platform.constants;perfil.fabricante="ios"===react_native_1.Platform.OS?"Apple":c?.Manufacturer}return semVazios(perfil)}exports.SDK_VERSAO="0.7.3-rc.
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true}),exports.SDK_VERSAO=void 0,exports.coletarPerfil=coletarPerfil;const react_native_1=require("react-native"),storage_1=require("./storage");function moduloPerfil(){const mods=react_native_1.NativeModules;return"ios"===react_native_1.Platform.OS?mods.PushMeshApns:mods.PushMeshFirebase}function timezoneId(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||void 0}catch{return}}function pais(){try{const loc=Intl.DateTimeFormat().resolvedOptions().locale,m=/[-_]([A-Za-z]{2})(?:[-_]|$)/.exec(loc);return m?m[1].toUpperCase():void 0}catch{return}}async function proximaSessao(){const atual=Number(await(0,storage_1.getItem)(storage_1.KEYS.sessoes)??"0"),proxima=Number.isFinite(atual)&&atual>=0?atual+1:1;return await(0,storage_1.setItem)(storage_1.KEYS.sessoes,String(proxima)),proxima}function semVazios(p){const out={};for(const[k,v]of Object.entries(p))null!=v&&""!==v&&(out[k]=v);return out}async function coletarPerfil(){const perfil={sdk_versao:exports.SDK_VERSAO,timezone_id:timezoneId(),pais:pais()};try{perfil.sessoes=await proximaSessao()}catch{}try{const nativo=moduloPerfil();if(nativo?.perfilDispositivo){const n=await nativo.perfilDispositivo();Object.assign(perfil,{device_os:n.device_os,fabricante:n.fabricante,modelo:n.modelo,net_type:n.net_type,carrier:n.carrier,rooted:n.rooted,standby_bucket:n.standby_bucket,bateria_irrestrita:n.bateria_irrestrita,notif_permissoes:n.notif_permissoes,instalacao_id:n.instalacao_id})}}catch{}if(!perfil.device_os){const v=react_native_1.Platform.Version;perfil.device_os="string"==typeof v?v:String(v)}if(!perfil.fabricante){const c=react_native_1.Platform.constants;perfil.fabricante="ios"===react_native_1.Platform.OS?"Apple":c?.Manufacturer}return semVazios(perfil)}exports.SDK_VERSAO="0.7.3-rc.4";
|
package/dist/cjs/permissions.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(o,m,k,k2){void 0===k2&&(k2=k);var desc=Object.getOwnPropertyDescriptor(m,k);desc&&!("get"in desc?!m.__esModule:desc.writable||desc.configurable)||(desc={enumerable:true,get:function(){return m[k]}}),Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){void 0===k2&&(k2=k),o[k2]=m[k]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(o,v){Object.defineProperty(o,"default",{enumerable:true,value:v})}:function(o,v){o.default=v}),__importStar=this&&this.__importStar||function(){var ownKeys=function(o){return ownKeys=Object.getOwnPropertyNames||function(o){var ar=[];for(var k in o)Object.prototype.hasOwnProperty.call(o,k)&&(ar[ar.length]=k);return ar},ownKeys(o)};return function(mod){if(mod&&mod.__esModule)return mod;var result={};if(null!=mod)for(var k=ownKeys(mod),i=0;i<k.length;i++)"default"!==k[i]&&__createBinding(result,mod,k[i]);return __setModuleDefault(result,mod),result}}();Object.defineProperty(exports,"__esModule",{value:true}),exports.mapAuthorizationStatus=mapAuthorizationStatus,exports.readNotificationTypes=readNotificationTypes,exports.canRequestNatively=canRequestNatively,exports.openNotificationSettings=openNotificationSettings,exports.reativarNotificacoes=reativarNotificacoes,exports.checkAndReport=checkAndReport,exports.markReativaPending=markReativaPending,exports.attachAppStateHook=attachAppStateHook,exports.detachAppStateHook=detachAppStateHook,exports.avisarSeMudo=avisarSeMudo;const react_native_1=__importStar(require("@notifee/react-native")),react_native_2=require("react-native"),queue_1=require("./queue"),state_1=require("./state"),storage_1=require("./storage"),types_1=require("./types");function mapAuthorizationStatus(status){switch(status){case react_native_1.AuthorizationStatus.AUTHORIZED:case react_native_1.AuthorizationStatus.PROVISIONAL:return types_1.RpNotificationTypes.Ativo;case react_native_1.AuthorizationStatus.DENIED:return types_1.RpNotificationTypes.Bloqueado;case react_native_1.AuthorizationStatus.NOT_DETERMINED:default:return types_1.RpNotificationTypes.NuncaPerguntou}}async function readNotificationTypes(){return mapAuthorizationStatus((await react_native_1.default.getNotificationSettings()).authorizationStatus)}async function canRequestNatively(){return(await react_native_1.default.getNotificationSettings()).authorizationStatus===react_native_1.AuthorizationStatus.NOT_DETERMINED&&("ios"===react_native_2.Platform.OS||"android"===react_native_2.Platform.OS&&Number(react_native_2.Platform.Version)>=33)}async function openNotificationSettings(){if("android"===react_native_2.Platform.OS)return void await react_native_1.default.openNotificationSettings();const nativo=react_native_2.NativeModules.PushMeshApns;if(nativo?.abrirAjustesDeNotificacao)try{if(await nativo.abrirAjustesDeNotificacao())return}catch{}await react_native_2.Linking.openSettings()}async function reativarNotificacoes(){return await canRequestNatively()?await react_native_1.default.requestPermission():await openNotificationSettings(),1===await checkAndReport()}async function checkAndReport(){const current=await readNotificationTypes(),previousRaw=await(0,storage_1.getItem)(storage_1.KEYS.notificationTypes),previous=null===previousRaw?null:Number(previousRaw);if(previous===current)return current;const playerId=state_1.state.playerId??await(0,storage_1.getItem)(storage_1.KEYS.playerId);if(playerId&&state_1.state.config){const{sendOrQueue:sendOrQueue}=await Promise.resolve().then(()=>__importStar(require("./queue")));await sendOrQueue("PUT",`/api/v1/players/${playerId}`,{app_id:(0,state_1.requireConfig)().appId,notification_types:current}),await(0,storage_1.setItem)(storage_1.KEYS.notificationTypes,String(current))}if(current===types_1.RpNotificationTypes.Ativo&&null!==previous&&previous!==types_1.RpNotificationTypes.Ativo){const reativaPending=await(0,storage_1.getItem)(storage_1.KEYS.reativaPending);if(reativaPending){const{track:track}=await Promise.resolve().then(()=>__importStar(require("./inapp")));await track("reativou",reativaPending),await(0,storage_1.setItem)(storage_1.KEYS.reativaPending,"")}}return current}async function markReativaPending(messageId){await(0,storage_1.setItem)(storage_1.KEYS.reativaPending,messageId)}function attachAppStateHook(){state_1.state.appStateSubscription||(state_1.state.appStateSubscription=react_native_2.AppState.addEventListener("change",nextState=>{if("active"===nextState){const bgDesde=state_1.state.emBackgroundDesde;state_1.state.emBackgroundDesde=null
|
|
1
|
+
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(o,m,k,k2){void 0===k2&&(k2=k);var desc=Object.getOwnPropertyDescriptor(m,k);desc&&!("get"in desc?!m.__esModule:desc.writable||desc.configurable)||(desc={enumerable:true,get:function(){return m[k]}}),Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){void 0===k2&&(k2=k),o[k2]=m[k]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(o,v){Object.defineProperty(o,"default",{enumerable:true,value:v})}:function(o,v){o.default=v}),__importStar=this&&this.__importStar||function(){var ownKeys=function(o){return ownKeys=Object.getOwnPropertyNames||function(o){var ar=[];for(var k in o)Object.prototype.hasOwnProperty.call(o,k)&&(ar[ar.length]=k);return ar},ownKeys(o)};return function(mod){if(mod&&mod.__esModule)return mod;var result={};if(null!=mod)for(var k=ownKeys(mod),i=0;i<k.length;i++)"default"!==k[i]&&__createBinding(result,mod,k[i]);return __setModuleDefault(result,mod),result}}();Object.defineProperty(exports,"__esModule",{value:true}),exports.mapAuthorizationStatus=mapAuthorizationStatus,exports.readNotificationTypes=readNotificationTypes,exports.canRequestNatively=canRequestNatively,exports.openNotificationSettings=openNotificationSettings,exports.reativarNotificacoes=reativarNotificacoes,exports.checkAndReport=checkAndReport,exports.markReativaPending=markReativaPending,exports.attachAppStateHook=attachAppStateHook,exports.detachAppStateHook=detachAppStateHook,exports.avisarSeMudo=avisarSeMudo;const react_native_1=__importStar(require("@notifee/react-native")),react_native_2=require("react-native"),queue_1=require("./queue"),state_1=require("./state"),storage_1=require("./storage"),types_1=require("./types");function mapAuthorizationStatus(status){switch(status){case react_native_1.AuthorizationStatus.AUTHORIZED:case react_native_1.AuthorizationStatus.PROVISIONAL:return types_1.RpNotificationTypes.Ativo;case react_native_1.AuthorizationStatus.DENIED:return types_1.RpNotificationTypes.Bloqueado;case react_native_1.AuthorizationStatus.NOT_DETERMINED:default:return types_1.RpNotificationTypes.NuncaPerguntou}}async function readNotificationTypes(){return mapAuthorizationStatus((await react_native_1.default.getNotificationSettings()).authorizationStatus)}async function canRequestNatively(){return(await react_native_1.default.getNotificationSettings()).authorizationStatus===react_native_1.AuthorizationStatus.NOT_DETERMINED&&("ios"===react_native_2.Platform.OS||"android"===react_native_2.Platform.OS&&Number(react_native_2.Platform.Version)>=33)}async function openNotificationSettings(){if("android"===react_native_2.Platform.OS)return void await react_native_1.default.openNotificationSettings();const nativo=react_native_2.NativeModules.PushMeshApns;if(nativo?.abrirAjustesDeNotificacao)try{if(await nativo.abrirAjustesDeNotificacao())return}catch{}await react_native_2.Linking.openSettings()}async function reativarNotificacoes(){return await canRequestNatively()?await react_native_1.default.requestPermission():await openNotificationSettings(),1===await checkAndReport()}async function checkAndReport(){const current=await readNotificationTypes(),previousRaw=await(0,storage_1.getItem)(storage_1.KEYS.notificationTypes),previous=null===previousRaw?null:Number(previousRaw);if(previous===current)return current;const playerId=state_1.state.playerId??await(0,storage_1.getItem)(storage_1.KEYS.playerId);if(playerId&&state_1.state.config){const{sendOrQueue:sendOrQueue}=await Promise.resolve().then(()=>__importStar(require("./queue")));await sendOrQueue("PUT",`/api/v1/players/${playerId}`,{app_id:(0,state_1.requireConfig)().appId,notification_types:current}),await(0,storage_1.setItem)(storage_1.KEYS.notificationTypes,String(current))}if(current===types_1.RpNotificationTypes.Ativo&&null!==previous&&previous!==types_1.RpNotificationTypes.Ativo){const reativaPending=await(0,storage_1.getItem)(storage_1.KEYS.reativaPending);if(reativaPending){const{track:track}=await Promise.resolve().then(()=>__importStar(require("./inapp")));await track("reativou",reativaPending),await(0,storage_1.setItem)(storage_1.KEYS.reativaPending,"")}}return current}async function markReativaPending(messageId){await(0,storage_1.setItem)(storage_1.KEYS.reativaPending,messageId)}function attachAppStateHook(){state_1.state.appStateSubscription||(state_1.state.appStateSubscription=react_native_2.AppState.addEventListener("change",nextState=>{if("active"===nextState){const bgDesde=state_1.state.emBackgroundDesde;state_1.state.emBackgroundDesde=null,!state_1.state.playerId&&state_1.state.token&&state_1.state.config?Promise.resolve().then(()=>__importStar(require("./players"))).then(m=>m.register()).catch(()=>{}).finally(()=>{(0,queue_1.flushQueue)().catch(()=>{})}):(0,queue_1.flushQueue)().catch(()=>{}),checkAndReport().catch(e=>console.warn("[PushMesh] checkAndReport falhou",e)),Promise.resolve().then(()=>__importStar(require("./inapp/lifecycle"))).then(m=>m.aoVoltarAoForeground(bgDesde)).catch(()=>{})}else null===state_1.state.emBackgroundDesde&&(state_1.state.emBackgroundDesde=Date.now())}))}function detachAppStateHook(){state_1.state.appStateSubscription?.remove(),state_1.state.appStateSubscription=null}function avisarSeMudo(tipos){if(1===tipos)return;const comoResolver="chame await PushMesh.permissions.reativarNotificacoes() no momento certo do seu fluxo, ou passe { pedirPermissao: true } no init para pedir logo no boot.";console.warn(0===tipos?`[PushMesh] Este aparelho está com a notificação BLOQUEADA. O push vai ser aceito pelo FCM/APNs e NÃO vai aparecer na tela — e o recibo de entrega nunca chega. Como resolver: ${comoResolver}`:`[PushMesh] A permissão de notificação ainda não foi pedida a esta pessoa (Android 13+ e iOS exigem o pedido). Enquanto isso o push é entregue e não aparece. Como resolver: ${comoResolver}`)}
|
package/dist/cjs/queue.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true}),exports.FLUSH_CONCURRENCY=void 0,exports.__resetQueueForTests=__resetQueueForTests,exports.__drainQueueLockForTests=__drainQueueLockForTests,exports.backoffMs=backoffMs,exports.enqueue=enqueue,exports.sendOrQueue=sendOrQueue,exports.flushQueue=flushQueue;const http_1=require("./http"),storage_1=require("./storage"),state_1=require("./state"),MAX_ATTEMPTS=10,MAX_QUEUE_ITEMS=500,BASE_DELAY_MS=1e3,MAX_DELAY_MS=3e5,JITTER_MS=1e3;exports.FLUSH_CONCURRENCY=5;let localId=0,ultimoNascimento=0;function agoraMonotonico(){return ultimoNascimento=Math.max(Date.now(),ultimoNascimento+1),ultimoNascimento}function nextId(){return localId+=1,`${agoraMonotonico()}-${localId}`}function criadoEm(item){return Number(item.id.split("-")[0])||0}function chaveEstado(item){if("PUT"!==item.method)return null;const campos=Object.keys(item.body).filter(c=>"app_id"!==c).sort().join(",");return`${item.path}#${campos}`}const superadoEm=new Map;function marcarSuperado(chave,quando){chave&&quando>(superadoEm.get(chave)??0)&&superadoEm.set(chave,quando)}function estaSuperado(item){const chave=chaveEstado(item);return null!==chave&&(superadoEm.get(chave)??0)>criadoEm(item)}function avisaDescarte(item,motivo){console.warn(`[PushMesh] ${item.method} ${item.path} descartado — ${motivo}`)}function coalescer(itens){const posicao=new Map,saida=[];for(const item of itens){if(estaSuperado(item))continue;const chave=chaveEstado(item);if(null===chave){saida.push(item);continue}const idx=posicao.get(chave);void 0===idx?posicao.set(chave,saida.push(item)-1):criadoEm(item)>=criadoEm(saida[idx])&&(saida[idx]=item)}return saida}let naoPersistidos=[];function __resetQueueForTests(){superadoEm.clear(),naoPersistidos=[]}function guardarEmMemoria(itens){naoPersistidos.push(...itens),naoPersistidos.length>MAX_QUEUE_ITEMS&&naoPersistidos.splice(0,naoPersistidos.length-MAX_QUEUE_ITEMS)}let cadeia=Promise.resolve();function comTrava(op){const proxima=cadeia.then(op,op);return cadeia=proxima.then(()=>{},()=>{}),proxima}async function __drainQueueLockForTests(){await cadeia}function backoffMs(attempts,jitter=Math.random){return Math.min(BASE_DELAY_MS*2**attempts,MAX_DELAY_MS)+Math.floor(jitter()*JITTER_MS)}async function enqueue(method,path,body,delayMs=0){const novo={id:nextId(),method:method,path:path,body:body,attempts:0,nextAttemptAt:Date.now()+delayMs};marcarSuperado(chaveEstado(novo),criadoEm(novo)),await comTrava(async()=>{const{valor:valor,falhou:falhou}=await(0,storage_1.getJsonSeguro)(storage_1.KEYS.queue,[]);if(falhou)return guardarEmMemoria([novo]),void console.warn("[PushMesh] fila ilegível agora (storage ocupado) — item guardado em memória");const queue=coalescer([...valor,...naoPersistidos,novo]);if(naoPersistidos=[],queue.length>MAX_QUEUE_ITEMS){const descartados=queue.length-MAX_QUEUE_ITEMS;queue.splice(0,descartados),console.warn(`[PushMesh] fila cheia (teto ${MAX_QUEUE_ITEMS}) — ${descartados} item(ns) antigo(s) descartado(s)`)}await(0,storage_1.setJson)(storage_1.KEYS.queue,queue)})}async function sendOrQueue(method,path,body){const nascimento=agoraMonotonico();try{const res=await(0,http_1.request)(method,path,body);return 429===res.status||res.status>=500?(await enqueue(method,path,body,res.retryAfterMs??backoffMs(1)),true):res.ok?(marcarSuperado(chaveEstado({method:method,path:path,body:body}),nascimento),await purgarSuperados(),true):(avisaDescarte({method:method,path:path},`${res.status}: retry não corrige payload inválido`),false)}catch(e){if(e instanceof http_1.NetworkError)return await enqueue(method,path,body),true;throw e}}async function purgarSuperados(){await comTrava(async()=>{const{valor:valor,falhou:falhou}=await(0,storage_1.getJsonSeguro)(storage_1.KEYS.queue,[]);if(!falhou&&valor.length>0){const vivos=valor.filter(item=>!estaSuperado(item));vivos.length!==valor.length&&await(0,storage_1.setJson)(storage_1.KEYS.queue,vivos)}const{valor:emVoo,falhou:falhouVoo}=await(0,storage_1.getJsonSeguro)(storage_1.KEYS.queueInflight,[]);if(!falhouVoo&&emVoo.length>0){const vivosVoo=emVoo.filter(item=>!estaSuperado(item));vivosVoo.length!==emVoo.length&&await(0,storage_1.setJson)(storage_1.KEYS.queueInflight,vivosVoo)}})}async function resolverPlayer(item){if(null!==item.body.player_id)return true;const playerId=state_1.state.playerId??await(0,storage_1.getItem)(storage_1.KEYS.playerId);return!!playerId&&(item.body={...item.body,player_id:playerId},true)}async function processItem(item,now){const retry=(delayMs,attempts)=>attempts<10?{...item,attempts:attempts,nextAttemptAt:now+delayMs}:null;if(estaSuperado(item))return avisaDescarte(item,"escrita mais nova do mesmo campo já foi enviada"),null;if(!await resolverPlayer(item))return
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true}),exports.FLUSH_CONCURRENCY=void 0,exports.__resetQueueForTests=__resetQueueForTests,exports.__drainQueueLockForTests=__drainQueueLockForTests,exports.backoffMs=backoffMs,exports.enqueue=enqueue,exports.sendOrQueue=sendOrQueue,exports.flushQueue=flushQueue;const http_1=require("./http"),storage_1=require("./storage"),state_1=require("./state"),MAX_ATTEMPTS=10,MAX_QUEUE_ITEMS=500,BASE_DELAY_MS=1e3,MAX_DELAY_MS=3e5,JITTER_MS=1e3;exports.FLUSH_CONCURRENCY=5;let localId=0,ultimoNascimento=0;function agoraMonotonico(){return ultimoNascimento=Math.max(Date.now(),ultimoNascimento+1),ultimoNascimento}function nextId(){return localId+=1,`${agoraMonotonico()}-${localId}`}function criadoEm(item){return Number(item.id.split("-")[0])||0}function chaveEstado(item){if("PUT"!==item.method)return null;const campos=Object.keys(item.body).filter(c=>"app_id"!==c).sort().join(",");return`${item.path}#${campos}`}const superadoEm=new Map;function marcarSuperado(chave,quando){chave&&quando>(superadoEm.get(chave)??0)&&superadoEm.set(chave,quando)}function estaSuperado(item){const chave=chaveEstado(item);return null!==chave&&(superadoEm.get(chave)??0)>criadoEm(item)}function avisaDescarte(item,motivo){console.warn(`[PushMesh] ${item.method} ${item.path} descartado — ${motivo}`)}function coalescer(itens){const posicao=new Map,saida=[];for(const item of itens){if(estaSuperado(item))continue;const chave=chaveEstado(item);if(null===chave){saida.push(item);continue}const idx=posicao.get(chave);void 0===idx?posicao.set(chave,saida.push(item)-1):criadoEm(item)>=criadoEm(saida[idx])&&(saida[idx]=item)}return saida}let naoPersistidos=[];function __resetQueueForTests(){superadoEm.clear(),naoPersistidos=[]}function guardarEmMemoria(itens){naoPersistidos.push(...itens),naoPersistidos.length>MAX_QUEUE_ITEMS&&naoPersistidos.splice(0,naoPersistidos.length-MAX_QUEUE_ITEMS)}let cadeia=Promise.resolve();function comTrava(op){const proxima=cadeia.then(op,op);return cadeia=proxima.then(()=>{},()=>{}),proxima}async function __drainQueueLockForTests(){await cadeia}function backoffMs(attempts,jitter=Math.random){return Math.min(BASE_DELAY_MS*2**attempts,MAX_DELAY_MS)+Math.floor(jitter()*JITTER_MS)}async function enqueue(method,path,body,delayMs=0){const novo={id:nextId(),method:method,path:path,body:body,attempts:0,nextAttemptAt:Date.now()+delayMs};marcarSuperado(chaveEstado(novo),criadoEm(novo)),await comTrava(async()=>{const{valor:valor,falhou:falhou}=await(0,storage_1.getJsonSeguro)(storage_1.KEYS.queue,[]);if(falhou)return guardarEmMemoria([novo]),void console.warn("[PushMesh] fila ilegível agora (storage ocupado) — item guardado em memória");const queue=coalescer([...valor,...naoPersistidos,novo]);if(naoPersistidos=[],queue.length>MAX_QUEUE_ITEMS){const descartados=queue.length-MAX_QUEUE_ITEMS;queue.splice(0,descartados),console.warn(`[PushMesh] fila cheia (teto ${MAX_QUEUE_ITEMS}) — ${descartados} item(ns) antigo(s) descartado(s)`)}await(0,storage_1.setJson)(storage_1.KEYS.queue,queue)})}async function sendOrQueue(method,path,body){const nascimento=agoraMonotonico();try{const res=await(0,http_1.request)(method,path,body);return 429===res.status||res.status>=500?(await enqueue(method,path,body,res.retryAfterMs??backoffMs(1)),true):res.ok?(marcarSuperado(chaveEstado({method:method,path:path,body:body}),nascimento),await purgarSuperados(),true):(avisaDescarte({method:method,path:path},`${res.status}: retry não corrige payload inválido`),false)}catch(e){if(e instanceof http_1.NetworkError)return await enqueue(method,path,body),true;throw e}}async function purgarSuperados(){await comTrava(async()=>{const{valor:valor,falhou:falhou}=await(0,storage_1.getJsonSeguro)(storage_1.KEYS.queue,[]);if(!falhou&&valor.length>0){const vivos=valor.filter(item=>!estaSuperado(item));vivos.length!==valor.length&&await(0,storage_1.setJson)(storage_1.KEYS.queue,vivos)}const{valor:emVoo,falhou:falhouVoo}=await(0,storage_1.getJsonSeguro)(storage_1.KEYS.queueInflight,[]);if(!falhouVoo&&emVoo.length>0){const vivosVoo=emVoo.filter(item=>!estaSuperado(item));vivosVoo.length!==emVoo.length&&await(0,storage_1.setJson)(storage_1.KEYS.queueInflight,vivosVoo)}})}async function resolverPlayer(item){if(null!==item.body.player_id)return true;const playerId=state_1.state.playerId??await(0,storage_1.getItem)(storage_1.KEYS.playerId);return!!playerId&&(item.body={...item.body,player_id:playerId},true)}async function processItem(item,now){const retry=(delayMs,attempts)=>attempts<10?{...item,attempts:attempts,nextAttemptAt:now+delayMs}:(avisaDescarte(item,"10 tentativas sem sucesso — desistindo"),null);if(estaSuperado(item))return avisaDescarte(item,"escrita mais nova do mesmo campo já foi enviada"),null;if(!await resolverPlayer(item))return{...item,nextAttemptAt:now+backoffMs(item.attempts+1)};try{const res=await(0,http_1.request)(item.method,item.path,item.body);return res.ok?null:429===res.status||res.status>=500?retry(res.retryAfterMs??backoffMs(item.attempts+1),item.attempts+1):(avisaDescarte(item,`${res.status}: retry não corrige payload inválido`),null)}catch{return retry(backoffMs(item.attempts+1),item.attempts+1)}}async function flushQueue(now=Date.now()){if(!state_1.state.flushing){state_1.state.flushing=true;try{const due=await comTrava(async()=>{const{valor:pendentes,falhou:falhou}=await(0,storage_1.getJsonSeguro)(storage_1.KEYS.queue,[]);if(falhou)return[];const{valor:emVoo,falhou:falhouVoo}=await(0,storage_1.getJsonSeguro)(storage_1.KEYS.queueInflight,[]);if(falhouVoo)return[];if(pendentes.length+emVoo.length+naoPersistidos.length===0)return[];const queue=coalescer([...emVoo,...pendentes,...naoPersistidos]);naoPersistidos=[];const prontos=queue.filter(item=>item.nextAttemptAt<=now),adiados=queue.filter(item=>item.nextAttemptAt>now);return await(0,storage_1.setJson)(storage_1.KEYS.queue,adiados),await(0,storage_1.setJson)(storage_1.KEYS.queueInflight,prontos),prontos});if(0===due.length)return;const devolver=[];let cursor=0;const worker=async()=>{for(;cursor<due.length;){const item=due[cursor++];try{const kept=await processItem(item,now);kept&&devolver.push(kept)}catch{devolver.push({...item,attempts:item.attempts+1,nextAttemptAt:now+backoffMs(item.attempts+1)})}}};await Promise.all(Array.from({length:Math.min(exports.FLUSH_CONCURRENCY,due.length)},()=>worker())),await comTrava(async()=>{const{valor:atual,falhou:falhou}=await(0,storage_1.getJsonSeguro)(storage_1.KEYS.queue,[]);if(falhou)return void guardarEmMemoria(devolver);const mesclado=coalescer([...devolver,...atual]);mesclado.length>MAX_QUEUE_ITEMS&&mesclado.splice(0,mesclado.length-MAX_QUEUE_ITEMS),await(0,storage_1.setJson)(storage_1.KEYS.queue,mesclado),await(0,storage_1.setJson)(storage_1.KEYS.queueInflight,[])})}finally{state_1.state.flushing=false}}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pushmesh/sdk",
|
|
3
|
-
"version": "0.7.3-rc.
|
|
3
|
+
"version": "0.7.3-rc.4",
|
|
4
4
|
"description": "React Native SDK for PushMesh — push notifications with real delivery receipts, permission re-activation and in-app banners. Classic API included. (Guia em português: README.pt-BR.md)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|