modelence 0.21.0 → 0.22.0-mt.dev.0

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.
Files changed (60) hide show
  1. package/dist/chunk-5DFWJU3M.js +3 -0
  2. package/dist/chunk-5DFWJU3M.js.map +1 -0
  3. package/dist/chunk-6BB456MV.js +4 -0
  4. package/dist/chunk-6BB456MV.js.map +1 -0
  5. package/dist/chunk-BJWGBMNX.js +3 -0
  6. package/dist/chunk-BJWGBMNX.js.map +1 -0
  7. package/dist/chunk-KYQ6UVLY.js +37 -0
  8. package/dist/chunk-KYQ6UVLY.js.map +1 -0
  9. package/dist/{chunk-SNADMLAT.js → chunk-MQQLQMPM.js} +2 -2
  10. package/dist/{chunk-SNADMLAT.js.map → chunk-MQQLQMPM.js.map} +1 -1
  11. package/dist/chunk-VF4RU7MF.js +3 -0
  12. package/dist/chunk-VF4RU7MF.js.map +1 -0
  13. package/dist/chunk-VYR7VQMQ.js +2 -0
  14. package/dist/chunk-VYR7VQMQ.js.map +1 -0
  15. package/dist/chunk-YM6DVNYH.js +2 -0
  16. package/dist/{chunk-TBGXZXAA.js.map → chunk-YM6DVNYH.js.map} +1 -1
  17. package/dist/chunk-ZEXT732Q.js +2 -0
  18. package/dist/chunk-ZEXT732Q.js.map +1 -0
  19. package/dist/client.d.ts +152 -4
  20. package/dist/client.js +1 -1
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +1 -1
  23. package/dist/{package-BVTS5E5V.js → package-Y67IHT4E.js} +2 -2
  24. package/dist/{package-BVTS5E5V.js.map → package-Y67IHT4E.js.map} +1 -1
  25. package/dist/render-G33LE5AY.js +2 -0
  26. package/dist/render-G33LE5AY.js.map +1 -0
  27. package/dist/renderApp-F7NZT5JC.js +2 -0
  28. package/dist/{renderApp-QYMNQ3KS.js.map → renderApp-F7NZT5JC.js.map} +1 -1
  29. package/dist/server-BEYRNZY5.js +2 -0
  30. package/dist/{server-KAHRRRDU.js.map → server-BEYRNZY5.js.map} +1 -1
  31. package/dist/server.d.ts +84 -8
  32. package/dist/server.js +1 -1
  33. package/dist/telemetry.d.ts +6 -1
  34. package/dist/telemetry.js +1 -1
  35. package/dist/transport-TR3OYHQR.js +2 -0
  36. package/dist/{transport-W6JIYZKZ.js.map → transport-TR3OYHQR.js.map} +1 -1
  37. package/dist/{types-B_R3eHmq.d.ts → types-B8uEAj0y.d.ts} +1 -1
  38. package/dist/{types-_BTBqn8b.d.ts → types-D_70a365.d.ts} +47 -2
  39. package/dist/types.d.ts +2 -2
  40. package/package.json +4 -6
  41. package/dist/chunk-3SGMDISS.js +0 -29
  42. package/dist/chunk-3SGMDISS.js.map +0 -1
  43. package/dist/chunk-7LPSX5A6.js +0 -3
  44. package/dist/chunk-7LPSX5A6.js.map +0 -1
  45. package/dist/chunk-KZZYA5HP.js +0 -3
  46. package/dist/chunk-KZZYA5HP.js.map +0 -1
  47. package/dist/chunk-MIRF7FP3.js +0 -2
  48. package/dist/chunk-MIRF7FP3.js.map +0 -1
  49. package/dist/chunk-SD3ERG2G.js +0 -3
  50. package/dist/chunk-SD3ERG2G.js.map +0 -1
  51. package/dist/chunk-TBGXZXAA.js +0 -2
  52. package/dist/chunk-YLLX26A4.js +0 -2
  53. package/dist/chunk-YLLX26A4.js.map +0 -1
  54. package/dist/chunk-YRR32LTF.js +0 -2
  55. package/dist/chunk-YRR32LTF.js.map +0 -1
  56. package/dist/render-STDR67WK.js +0 -2
  57. package/dist/render-STDR67WK.js.map +0 -1
  58. package/dist/renderApp-QYMNQ3KS.js +0 -2
  59. package/dist/server-KAHRRRDU.js +0 -2
  60. package/dist/transport-W6JIYZKZ.js +0 -2
@@ -1,2 +1,2 @@
1
- import {B}from'./chunk-SD3ERG2G.js';import {a,b,c}from'./chunk-5M6FUMUK.js';import {AsyncLocalStorage}from'async_hooks';async function x(t,e,u){let n=a(await B(t,e,u)),a$1=b(n),y=JSON.parse(JSON.stringify(n));return c(y,a$1??void 0)}var p=new AsyncLocalStorage;function g(t,e){return p.run(t,e)}function d(){return p.getStore()}export{x as a,g as b,d as c};//# sourceMappingURL=chunk-SNADMLAT.js.map
2
- //# sourceMappingURL=chunk-SNADMLAT.js.map
1
+ import {F}from'./chunk-6BB456MV.js';import {a,b,c}from'./chunk-5M6FUMUK.js';import {AsyncLocalStorage}from'async_hooks';async function x(t,e,u){let n=a(await F(t,e,u)),a$1=b(n),y=JSON.parse(JSON.stringify(n));return c(y,a$1??void 0)}var p=new AsyncLocalStorage;function g(t,e){return p.run(t,e)}function d(){return p.getStore()}export{x as a,g as b,d as c};//# sourceMappingURL=chunk-MQQLQMPM.js.map
2
+ //# sourceMappingURL=chunk-MQQLQMPM.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ssr/callInProcess.ts","../src/ssr/context.ts"],"names":["callInProcessMethod","methodName","args","context","sanitized","sanitizeResult","runMethod","typeMap","getResponseTypeMap","jsonRoundTripped","reviveResponseTypes","storage","AsyncLocalStorage","runWithSsrContext","ctx","fn","getSsrContext"],"mappings":"wHAOA,eAAsBA,CAAAA,CACpBC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACY,CACZ,IAAMC,CAAAA,CAAYC,CAAAA,CAAe,MAAMC,CAAAA,CAAUL,CAAAA,CAAYC,CAAAA,CAAMC,CAAO,CAAC,CAAA,CACrEI,GAAAA,CAAUC,CAAAA,CAAmBJ,CAAS,CAAA,CACtCK,CAAAA,CAAmB,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAUL,CAAS,CAAC,CAAA,CAC7D,OAAOM,CAAAA,CAAoBD,CAAAA,CAAkBF,GAAAA,EAAW,MAAS,CACnE,CCAA,IAAMI,CAAAA,CAAU,IAAIC,iBAAAA,CAEb,SAASC,CAAAA,CAAqBC,CAAAA,CAAwBC,CAAAA,CAAgB,CAC3E,OAAOJ,CAAAA,CAAQ,GAAA,CAAIG,CAAAA,CAAKC,CAAE,CAC5B,CAEO,SAASC,CAAAA,EAA+C,CAC7D,OAAOL,CAAAA,CAAQ,QAAA,EACjB","file":"chunk-SNADMLAT.js","sourcesContent":["import { runMethod } from '../methods';\nimport { sanitizeResult, getResponseTypeMap, reviveResponseTypes } from '../methods/serialize';\nimport type { Context, Args } from '../methods/types';\n\n// Invoke a method in-process and round-trip through the same JSON pipeline\n// as the HTTP transport so SSR output matches the dehydrated query cache.\n// The JSON.stringify/parse step is load-bearing: strips `undefined` props.\nexport async function callInProcessMethod<T = unknown>(\n methodName: string,\n args: Args,\n context: Context\n): Promise<T> {\n const sanitized = sanitizeResult(await runMethod(methodName, args, context));\n const typeMap = getResponseTypeMap(sanitized);\n const jsonRoundTripped = JSON.parse(JSON.stringify(sanitized));\n return reviveResponseTypes(jsonRoundTripped, typeMap ?? undefined) as T;\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { QueryClient } from '@tanstack/react-query';\nimport type { Context } from '../methods/types';\nimport type { Configs } from '../config/types';\n\nexport type SsrSessionSnapshot = {\n user: unknown;\n configs: Configs;\n};\n\nexport type SsrRequestContext = {\n callContext: Context;\n queryClient: QueryClient;\n session: SsrSessionSnapshot;\n};\n\nconst storage = new AsyncLocalStorage<SsrRequestContext>();\n\nexport function runWithSsrContext<T>(ctx: SsrRequestContext, fn: () => T): T {\n return storage.run(ctx, fn);\n}\n\nexport function getSsrContext(): SsrRequestContext | undefined {\n return storage.getStore();\n}\n"]}
1
+ {"version":3,"sources":["../src/ssr/callInProcess.ts","../src/ssr/context.ts"],"names":["callInProcessMethod","methodName","args","context","sanitized","sanitizeResult","runMethod","typeMap","getResponseTypeMap","jsonRoundTripped","reviveResponseTypes","storage","AsyncLocalStorage","runWithSsrContext","ctx","fn","getSsrContext"],"mappings":"wHAOA,eAAsBA,CAAAA,CACpBC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACY,CACZ,IAAMC,CAAAA,CAAYC,CAAAA,CAAe,MAAMC,CAAAA,CAAUL,CAAAA,CAAYC,CAAAA,CAAMC,CAAO,CAAC,CAAA,CACrEI,GAAAA,CAAUC,CAAAA,CAAmBJ,CAAS,CAAA,CACtCK,CAAAA,CAAmB,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAUL,CAAS,CAAC,CAAA,CAC7D,OAAOM,CAAAA,CAAoBD,CAAAA,CAAkBF,GAAAA,EAAW,MAAS,CACnE,CCAA,IAAMI,CAAAA,CAAU,IAAIC,iBAAAA,CAEb,SAASC,CAAAA,CAAqBC,CAAAA,CAAwBC,CAAAA,CAAgB,CAC3E,OAAOJ,CAAAA,CAAQ,GAAA,CAAIG,CAAAA,CAAKC,CAAE,CAC5B,CAEO,SAASC,CAAAA,EAA+C,CAC7D,OAAOL,CAAAA,CAAQ,QAAA,EACjB","file":"chunk-MQQLQMPM.js","sourcesContent":["import { runMethod } from '../methods';\nimport { sanitizeResult, getResponseTypeMap, reviveResponseTypes } from '../methods/serialize';\nimport type { Context, Args } from '../methods/types';\n\n// Invoke a method in-process and round-trip through the same JSON pipeline\n// as the HTTP transport so SSR output matches the dehydrated query cache.\n// The JSON.stringify/parse step is load-bearing: strips `undefined` props.\nexport async function callInProcessMethod<T = unknown>(\n methodName: string,\n args: Args,\n context: Context\n): Promise<T> {\n const sanitized = sanitizeResult(await runMethod(methodName, args, context));\n const typeMap = getResponseTypeMap(sanitized);\n const jsonRoundTripped = JSON.parse(JSON.stringify(sanitized));\n return reviveResponseTypes(jsonRoundTripped, typeMap ?? undefined) as T;\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { QueryClient } from '@tanstack/react-query';\nimport type { Context } from '../methods/types';\nimport type { Configs } from '../config/types';\n\nexport type SsrSessionSnapshot = {\n user: unknown;\n configs: Configs;\n};\n\nexport type SsrRequestContext = {\n callContext: Context;\n queryClient: QueryClient;\n session: SsrSessionSnapshot;\n};\n\nconst storage = new AsyncLocalStorage<SsrRequestContext>();\n\nexport function runWithSsrContext<T>(ctx: SsrRequestContext, fn: () => T): T {\n return storage.run(ctx, fn);\n}\n\nexport function getSsrContext(): SsrRequestContext | undefined {\n return storage.getStore();\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import P from'elastic-apm-node';import v from'winston';import {ElasticsearchTransport}from'winston-elasticsearch';import l from'process';var f={},L={},S=false;function d(t){return L[t]?.value??f[t]?.default}function G(){if(!S)throw new Error("Config is not initialized: an attempt was made to access configs before they were loaded");return Object.fromEntries(Object.entries(f).filter(([t,e])=>e.isPublic).map(([t,e])=>[t,{key:t,type:e.type,value:L[t]?.value??e.default}]))}function Y(t){t.forEach(({key:e,type:o,value:n})=>{!e.toLowerCase().startsWith("_system.")&&!f[e]||(L[e]={key:e,type:o,value:n});}),S=true;}function $(){return f}function F(t){Object.entries(t).forEach(([e,o])=>{let{type:n,isPublic:r}=o;if(n==="secret"&&r)throw new Error(`Config ${e} with type "secret" cannot be public`)}),f=t;}var s={stdout:[{log:"",timestamp:null}],stderr:[{log:"",timestamp:null}]},z=1;function I({elasticCloudId:t,elasticApiKey:e}){let o=l.stdout.write,n=l.stderr.write;l.stdout.write=function(r,...i){return h(r.toString(),s.stdout),o.call(l.stdout,r,...i)},l.stderr.write=function(r,...i){return h(r.toString(),s.stderr),n.call(l.stderr,r,...i)},T();}function h(t,e){if(t.length===0)return;let o=new Date;for(let n=0;n<t.length;n++){let r=e[e.length-1];r.timestamp||(r.timestamp=o,r.sequenceId=z++),t[n]===`
2
+ `?e.push({log:"",timestamp:null}):r.log+=t[n];}}async function N(){let t=s.stdout.slice(0,-1);s.stdout=[s.stdout[s.stdout.length-1]];let e=s.stderr.slice(0,-1);s.stderr=[s.stderr[s.stderr.length-1]],t.forEach(({log:o,timestamp:n,sequenceId:r})=>{b(o,{timestamp:n,source:"console",sequenceId:r});}),e.forEach(({log:o,timestamp:n,sequenceId:r})=>{w(o,{timestamp:n,source:"console",sequenceId:r});});}function T(){setTimeout(()=>{N(),T();},1e3);}var c=null;function Z(){}function tt(t){c=Object.assign({},c,t);}function j(){return c?.environmentId}function K(){return c?.appAlias}function R(){return c?.environmentAlias}function M(){return c?.telemetry?.serviceName}function a(){return !!c?.telemetry?.isEnabled}var _=false,p=null,m=null,ct=async()=>{if(_)throw new Error('Metrics are already initialized, duplicate "initMetrics" call received');_=true,a()&&await W();};async function W(){let t=d("_system.elastic.apmEndpoint"),e=d("_system.elastic.cloudId"),o=d("_system.elastic.apiKey"),n=K()??"unknown",r=R()??"unknown",i=j()??"unknown",g=M();p=P.start({serviceName:g,apiKey:o,serverUrl:t,transactionSampleRate:1,centralConfig:false,globalLabels:{modelenceEnv:"dev",appEnv:"dev",environmentId:i,appAlias:n,environmentAlias:r}});let u=new ElasticsearchTransport({apm:p,level:"debug",clientOpts:{cloud:{id:e},auth:{apiKey:o},requestTimeout:1e4,tls:{rejectUnauthorized:false}},bufferLimit:1e3,silent:false});u.on("error",O=>{console.error("Elasticsearch Transport Error:",O);}),m=v.createLogger({level:"debug",defaultMeta:{serviceName:g},format:v.format.combine(v.format.json()),transports:[u]}),I({elasticCloudId:e,elasticApiKey:o});}function A(){if(!p)throw new Error("APM is not initialized");return p}function y(){return m!==null}function E(){if(!m)throw new Error("Logger is not initialized");return m}var k=["token","password","secret","nonce","code"];function C(t){if(!t||typeof t!="object")return t;if(Array.isArray(t))return t.map(C);let e={};for(let[o,n]of Object.entries(t)){let r=k.some(i=>o.toLowerCase().includes(i));e[o]=r?"[redacted]":C(n);}return e}function x(){let t="";return a()||(t="info"),process.env.MODELENCE_LOG_LEVEL||t}function q(t,e){a()&&y()&&E().debug(t,e),x()==="debug"&&console.debug(t,e);}function b(t,e){a()&&y()&&E().info(t,e),["debug","info"].includes(x())&&console.info(t,e);}function w(t,e){a()&&y()&&E().error(t,e),["debug","info","error"].includes(x())&&console.error(t,e);}function U(t,e,o){if(!a())return {end:()=>{},setContext:()=>{}};let n=A(),r=n.startTransaction(e,t);return o&&n.setCustomContext(o),{end:(i,{endTime:g,context:u}={})=>{u&&n.setCustomContext(u),r.end(i,g);},setContext:i=>{n.setCustomContext(i);}}}function V(t){if(!a()){console.error(t);return}A().captureError(t);}export{d as a,G as b,Y as c,$ as d,F as e,Z as f,tt as g,ct as h,C as i,q as j,b as k,w as l,U as m,V as n};//# sourceMappingURL=chunk-VF4RU7MF.js.map
3
+ //# sourceMappingURL=chunk-VF4RU7MF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/server.ts","../src/app/loggerProcess.ts","../src/app/state.ts","../src/app/metrics.ts","../src/telemetry/index.ts"],"names":["configSchema","config","isInitialized","getConfig","key","getPublicConfigs","_","schema","loadConfigs","configs","type","value","getSchema","setSchema","isPublic","buffer","sequenceId","startLoggerProcess","_elasticCloudId","_elasticApiKey","originalStdoutWrite","process","originalStderrWrite","chunk","args","addToBuffer","loopSendLogs","timestamp","i","current","sendLogs","stdoutLogs","stderrLogs","log","logInfo","logError","metadata","markAppStarted","setMetadata","_metadata","getEnvironmentId","getAppAlias","getEnvironmentAlias","getTelemetryServiceName","isTelemetryEnabled","apm","logger","initMetrics","initElasticApm","elasticApmEndpoint","elasticCloudId","elasticApiKey","appAlias","environmentAlias","environmentId","serviceName","elasticApm","esTransport","ElasticsearchTransport","error","winston","getApm","isLoggerReady","getLogger","SENSITIVE_KEYS","redactSensitive","result","val","isSensitive","k","getLogLevel","defaultLoglevel","logDebug","message","startTransaction","name","context","transaction","endTime","captureError"],"mappings":"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","file":"chunk-VF4RU7MF.js","sourcesContent":["import { AppConfig, ConfigKey, ConfigSchema } from './types';\n\nlet configSchema: ConfigSchema = {};\nlet config: Record<ConfigKey, AppConfig> = {};\nlet isInitialized = false;\n\n/**\n * @sidebarTitle getConfig (server)\n *\n * @param key - The configuration key to retrieve\n * @returns The configuration value (string, number, or boolean)\n *\n * @example\n * ```ts\n * import { getConfig } from 'modelence/server';\n *\n * // Get the site URL\n * const siteUrl = getConfig('_system.site.url');\n * ```\n *\n * Set via environment variable:\n * ```bash\n * MODELENCE_SITE_URL=https://myapp.com\n * ```\n *\n * @example\n * ```ts\n * import { getConfig } from 'modelence/server';\n *\n * // Get the current environment (e.g., 'development', 'staging', 'production')\n * const env = getConfig('_system.env');\n *\n * if (env === 'production') {\n * // Enable production features\n * }\n * ```\n *\n * Set via environment variable:\n * ```bash\n * MODELENCE_SITE_ENV=production\n * ```\n */\nexport function getConfig(key: ConfigKey): string | number | boolean | undefined {\n return config[key]?.value ?? configSchema[key]?.default;\n}\n\nexport function getPublicConfigs() {\n if (!isInitialized) {\n throw new Error(\n 'Config is not initialized: an attempt was made to access configs before they were loaded'\n );\n }\n\n return Object.fromEntries(\n Object.entries(configSchema)\n .filter(([_, schema]) => schema.isPublic)\n .map(([key, schema]) => {\n return [\n key,\n {\n key,\n type: schema.type,\n value: config[key]?.value ?? schema.default,\n },\n ];\n })\n );\n}\n\nexport function loadConfigs(configs: AppConfig[]) {\n configs.forEach(({ key, type, value }) => {\n const isSystemConfig = key.toLowerCase().startsWith('_system.');\n\n if (!isSystemConfig && !configSchema[key]) {\n // Ignore unknown configs\n return;\n }\n\n config[key] = {\n key,\n type,\n value,\n };\n });\n\n isInitialized = true;\n}\n\nexport function getSchema() {\n return configSchema;\n}\n\nexport function setSchema(schema: ConfigSchema) {\n // TODO: more validation on the schema structure\n Object.entries(schema).forEach(([key, value]) => {\n const { type, isPublic } = value;\n\n if (type === 'secret' && isPublic) {\n throw new Error(`Config ${key} with type \"secret\" cannot be public`);\n }\n });\n\n configSchema = schema;\n}\n","// import { spawn } from 'child_process';\n// import { fileURLToPath } from 'url';\n// import { dirname, join } from 'path';\nimport { logInfo, logError } from '@/telemetry';\nimport process from 'process';\n\ntype LogEntry = { log: string; timestamp: Date | null; sequenceId?: number };\ntype LogBuffer = LogEntry[];\n\nconst buffer: { stdout: LogBuffer; stderr: LogBuffer } = {\n stdout: [{ log: '', timestamp: null }],\n stderr: [{ log: '', timestamp: null }],\n};\n\nlet sequenceId = 1;\n\nexport function startLoggerProcess({\n elasticCloudId: _elasticCloudId,\n elasticApiKey: _elasticApiKey,\n}: {\n elasticCloudId: string;\n elasticApiKey: string;\n}) {\n const originalStdoutWrite = process.stdout.write;\n const originalStderrWrite = process.stderr.write;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n process.stdout.write = function (chunk: string | Uint8Array, ...args: any[]) {\n addToBuffer(chunk.toString(), buffer.stdout);\n return originalStdoutWrite.call(process.stdout, chunk, ...args);\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n process.stderr.write = function (chunk: string | Uint8Array, ...args: any[]) {\n addToBuffer(chunk.toString(), buffer.stderr);\n return originalStderrWrite.call(process.stderr, chunk, ...args);\n };\n\n loopSendLogs();\n\n // const currentFilePath = fileURLToPath(import.meta.url);\n // const projectRoot = dirname(dirname(currentFilePath));\n // const loggerPath = join(projectRoot, 'bin', 'modelence-logger', 'index.js');\n // const logger = spawn(process.execPath, [loggerPath], {\n // env: {\n // NODE_ENV: process.env.NODE_ENV,\n // ELASTIC_CLOUD_ID: elasticCloudId,\n // ELASTIC_API_KEY: elasticApiKey\n // },\n // stdio: ['pipe', 'inherit', 'inherit'],\n // detached: true\n // });\n\n // const originalStdoutWrite = process.stdout.write;\n // const originalStderrWrite = process.stderr.write;\n\n // process.stdout.write = function(chunk: any, ...args: any[]) {\n // logger.stdin.write(chunk);\n // return originalStdoutWrite.apply(process.stdout, [chunk, ...args]);\n // };\n\n // process.stderr.write = function(chunk: any, ...args: any[]) {\n // logger.stdin.write(chunk);\n // return originalStderrWrite.apply(process.stderr, [chunk, ...args]);\n // };\n\n // process.on('exit', () => {\n // process.stdout.write = originalStdoutWrite;\n // process.stderr.write = originalStderrWrite;\n // });\n\n // logger.unref();\n}\n\nfunction addToBuffer(chunk: string, buffer: LogBuffer) {\n if (chunk.length === 0) {\n return;\n }\n\n const timestamp = new Date();\n\n for (let i = 0; i < chunk.length; i++) {\n const current = buffer[buffer.length - 1];\n if (!current.timestamp) {\n current.timestamp = timestamp;\n current.sequenceId = sequenceId++;\n }\n\n if (chunk[i] === '\\n') {\n buffer.push({ log: '', timestamp: null });\n } else {\n current.log += chunk[i];\n }\n }\n}\n\nasync function sendLogs() {\n const stdoutLogs = buffer.stdout.slice(0, -1);\n buffer.stdout = [buffer.stdout[buffer.stdout.length - 1]];\n\n const stderrLogs = buffer.stderr.slice(0, -1);\n buffer.stderr = [buffer.stderr[buffer.stderr.length - 1]];\n\n stdoutLogs.forEach(({ log, timestamp, sequenceId }: LogEntry) => {\n logInfo(log, { timestamp, source: 'console', sequenceId });\n });\n stderrLogs.forEach(({ log, timestamp, sequenceId }: LogEntry) => {\n logError(log, { timestamp, source: 'console', sequenceId });\n });\n}\n\nfunction loopSendLogs() {\n setTimeout(() => {\n void sendLogs();\n loopSendLogs();\n }, 1000);\n}\n","type AppMetadata = {\n environmentId: string;\n appAlias: string;\n environmentAlias: string;\n telemetry: {\n isEnabled: boolean;\n serviceName: string;\n };\n};\n\nlet appStarted = false;\nlet metadata: AppMetadata | null = null;\n\nexport function markAppStarted() {\n appStarted = true;\n}\n\nexport function isAppStarted() {\n return appStarted;\n}\n\nexport function setMetadata(_metadata: AppMetadata) {\n metadata = Object.assign({}, metadata, _metadata);\n}\n\nexport function getEnvironmentId() {\n return metadata?.environmentId;\n}\n\nexport function getAppAlias() {\n return metadata?.appAlias;\n}\n\nexport function getEnvironmentAlias() {\n return metadata?.environmentAlias;\n}\n\nexport function getTelemetryServiceName() {\n return metadata?.telemetry?.serviceName;\n}\n\nexport function isTelemetryEnabled() {\n return Boolean(metadata?.telemetry?.isEnabled);\n}\n","import elasticApm from 'elastic-apm-node';\nimport winston from 'winston';\nimport { ElasticsearchTransport } from 'winston-elasticsearch';\n\nimport { getConfig } from '../config/server';\nimport { startLoggerProcess } from './loggerProcess';\nimport {\n getAppAlias,\n getEnvironmentAlias,\n getEnvironmentId,\n getTelemetryServiceName,\n isTelemetryEnabled,\n} from './state';\n\nlet isInitialized = false;\nlet apm: typeof elasticApm | null = null;\nlet logger: winston.Logger | null = null;\n\nexport const initMetrics = async () => {\n if (isInitialized) {\n throw new Error('Metrics are already initialized, duplicate \"initMetrics\" call received');\n }\n\n isInitialized = true;\n\n if (isTelemetryEnabled()) {\n await initElasticApm();\n }\n};\n\nasync function initElasticApm() {\n const elasticApmEndpoint = getConfig('_system.elastic.apmEndpoint') as string;\n const elasticCloudId = getConfig('_system.elastic.cloudId') as string;\n const elasticApiKey = getConfig('_system.elastic.apiKey') as string;\n\n const appAlias = getAppAlias() ?? 'unknown';\n const environmentAlias = getEnvironmentAlias() ?? 'unknown';\n const environmentId = getEnvironmentId() ?? 'unknown';\n const serviceName = getTelemetryServiceName();\n\n apm = elasticApm.start({\n serviceName,\n apiKey: elasticApiKey,\n serverUrl: elasticApmEndpoint,\n // environment: 'dev',\n transactionSampleRate: 1.0,\n centralConfig: false,\n globalLabels: {\n modelenceEnv: 'dev',\n appEnv: 'dev',\n environmentId,\n appAlias,\n environmentAlias,\n },\n // logLevel: 'debug'\n });\n\n const esTransport = new ElasticsearchTransport({\n apm,\n level: 'debug',\n clientOpts: {\n cloud: {\n id: elasticCloudId,\n },\n auth: {\n apiKey: elasticApiKey,\n },\n requestTimeout: 10000,\n tls: {\n rejectUnauthorized: false,\n },\n },\n bufferLimit: 1000,\n silent: false,\n });\n\n esTransport.on('error', (error) => {\n console.error('Elasticsearch Transport Error:', error);\n });\n\n logger = winston.createLogger({\n level: 'debug',\n defaultMeta: {\n serviceName,\n },\n format: winston.format.combine(winston.format.json()),\n transports: [esTransport],\n });\n\n startLoggerProcess({\n elasticCloudId,\n elasticApiKey,\n });\n}\n\nexport function getApm() {\n if (!apm) {\n throw new Error('APM is not initialized');\n }\n return apm;\n}\n\nexport function isLoggerReady() {\n return logger !== null;\n}\n\nexport function getLogger() {\n if (!logger) {\n throw new Error('Logger is not initialized');\n }\n return logger;\n}\n","import { getLogger, getApm, isLoggerReady } from '@/app/metrics';\nimport { isTelemetryEnabled } from '@/app/state';\n\ntype LogLevel = 'error' | 'info' | 'debug' | '';\n\n// Secret-bearing keys to scrub before request args/query/body reach the APM sink.\n// Matched case-insensitively as a substring (`authToken` matches `token`).\nconst SENSITIVE_KEYS = ['token', 'password', 'secret', 'nonce', 'code'];\n\n/**\n * Deep-copies `value`, replacing any {@link SENSITIVE_KEYS} match with\n * `'[redacted]'`. Non-object values pass through unchanged.\n */\nexport function redactSensitive(value: unknown): unknown {\n if (!value || typeof value !== 'object') {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map(redactSensitive);\n }\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n const isSensitive = SENSITIVE_KEYS.some((k) => key.toLowerCase().includes(k));\n result[key] = isSensitive ? '[redacted]' : redactSensitive(val);\n }\n return result;\n}\n\n/**\n * Gets the logging level for console logs based on the MODELENCE_LOG_LEVEL environment variable.\n *\n * @returns The log level ('error' | 'info' | 'debug' | '')\n *\n * Behavior:\n * - If MODELENCE_LOG_LEVEL is set, returns that value\n * - If telemetry is disabled and MODELENCE_LOG_LEVEL is not set, defaults to 'info'\n * - If telemetry is enabled and MODELENCE_LOG_LEVEL is not set, returns '' (no console logging)\n */\nfunction getLogLevel(): LogLevel {\n let defaultLoglevel: LogLevel = '';\n if (!isTelemetryEnabled()) {\n defaultLoglevel = 'info';\n }\n\n return (process.env.MODELENCE_LOG_LEVEL as LogLevel) || defaultLoglevel;\n}\n\nexport function logDebug(message: string, args: object) {\n if (isTelemetryEnabled() && isLoggerReady()) {\n getLogger().debug(message, args);\n }\n if (getLogLevel() === 'debug') {\n console.debug(message, args);\n }\n}\n\nexport function logInfo(message: string, args: object) {\n if (isTelemetryEnabled() && isLoggerReady()) {\n getLogger().info(message, args);\n }\n if (['debug', 'info'].includes(getLogLevel())) {\n console.info(message, args);\n }\n}\n\nexport function logError(message: string, args: object) {\n if (isTelemetryEnabled() && isLoggerReady()) {\n getLogger().error(message, args);\n }\n if (['debug', 'info', 'error'].includes(getLogLevel())) {\n console.error(message, args);\n }\n}\n\ninterface WrappedTransaction {\n end(result?: string, context?: Record<string, unknown>): void;\n setContext(context: Record<string, unknown>): void;\n}\n\nexport function startTransaction(\n type: 'method' | 'cron' | 'ai' | 'custom' | 'route',\n name: string,\n context?: Record<string, unknown>\n): WrappedTransaction {\n if (!isTelemetryEnabled()) {\n return {\n end: () => {\n // do nothing\n },\n setContext: () => {\n // do nothing\n },\n };\n }\n\n const apm = getApm();\n const transaction = apm.startTransaction(name, type);\n if (context) {\n apm.setCustomContext(context);\n }\n\n return {\n end: (\n result?: string,\n { endTime, context }: { endTime?: number; context?: Record<string, unknown> } = {}\n ) => {\n if (context) {\n apm.setCustomContext(context);\n }\n transaction.end(result, endTime);\n },\n setContext: (context: Record<string, unknown>) => {\n apm.setCustomContext(context);\n },\n };\n}\n\nexport function captureError(error: Error) {\n if (!isTelemetryEnabled()) {\n console.error(error);\n return;\n }\n\n getApm().captureError(error);\n}\n"]}
@@ -0,0 +1,2 @@
1
+ var t=class extends Error{},a=class extends t{constructor(s,e){super(s);this.status=401;this.name="AuthError",this.code=e;}},c=class extends t{constructor(s,e){super(s);this.status=400;this.name="ValidationError",this.code=e;}},o=class extends t{constructor(s){super(s);this.status=429;this.name="RateLimitError";}};export{t as a,a as b,c,o as d};//# sourceMappingURL=chunk-VYR7VQMQ.js.map
2
+ //# sourceMappingURL=chunk-VYR7VQMQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/error.ts"],"names":["ModelenceError","AuthError","message","code","ValidationError","RateLimitError"],"mappings":"AAAO,IAAeA,CAAAA,CAAf,cAAsC,KAAM,EAOnD,CAEaC,CAAAA,CAAN,cAAwBD,CAAe,CAG5C,WAAA,CAAYE,CAAAA,CAAiBC,CAAAA,CAAe,CAC1C,KAAA,CAAMD,CAAO,CAAA,CAHf,IAAA,CAAA,MAAA,CAAS,GAAA,CAIP,IAAA,CAAK,IAAA,CAAO,WAAA,CACZ,IAAA,CAAK,IAAA,CAAOC,EACd,CACF,CAAA,CAEaC,CAAAA,CAAN,cAA8BJ,CAAe,CAGlD,WAAA,CAAYE,CAAAA,CAAiBC,CAAAA,CAAe,CAC1C,KAAA,CAAMD,CAAO,CAAA,CAHf,IAAA,CAAA,MAAA,CAAS,GAAA,CAIP,IAAA,CAAK,IAAA,CAAO,iBAAA,CACZ,IAAA,CAAK,IAAA,CAAOC,EACd,CACF,CAAA,CAEaE,CAAAA,CAAN,cAA6BL,CAAe,CAGjD,WAAA,CAAYE,CAAAA,CAAiB,CAC3B,KAAA,CAAMA,CAAO,CAAA,CAHf,IAAA,CAAA,MAAA,CAAS,GAAA,CAIP,IAAA,CAAK,IAAA,CAAO,iBACd,CACF","file":"chunk-VYR7VQMQ.js","sourcesContent":["export abstract class ModelenceError extends Error {\n abstract status: number;\n /**\n * Optional machine-readable error code so clients can branch on the kind of\n * error without string-matching `message` (which may be reworded or localized).\n */\n code?: string;\n}\n\nexport class AuthError extends ModelenceError {\n status = 401;\n\n constructor(message: string, code?: string) {\n super(message);\n this.name = 'AuthError';\n this.code = code;\n }\n}\n\nexport class ValidationError extends ModelenceError {\n status = 400;\n\n constructor(message: string, code?: string) {\n super(message);\n this.name = 'ValidationError';\n this.code = code;\n }\n}\n\nexport class RateLimitError extends ModelenceError {\n status = 429;\n\n constructor(message: string) {\n super(message);\n this.name = 'RateLimitError';\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import {a,d,g,n}from'./chunk-ZEXT732Q.js';import {y,A,u as u$1,B,F}from'./chunk-BJWGBMNX.js';import R from'react';import E from'react-dom/client';import {jsx}from'react/jsx-runtime';function c(t){return {getConfig(e){return A(`${t}.${e}`)},query(e,...r){let o=r[0]??{};return {queryKey:[t,e,o],queryFn:()=>y(`${t}.${e}`,o)}},mutation(e){return {mutationFn:r=>y(`${t}.${e}`,r)}},infiniteQuery(e,r){return {queryKey:[t,e,"infinite",r(void 0)],initialPageParam:void 0,queryFn:({pageParam:o})=>y(`${t}.${e}`,r(o))}}}}var _=c("_system");var u=class{constructor(e,r){this.category=e,this.onMessage=r;}init(){d()?.on({category:this.category,listener:this.onMessage});}joinChannel(e){d()?.joinChannel({category:this.category,id:e});}leaveChannel(e){d()?.leaveChannel({category:this.category,id:e});}};var C="useClient"in R?R.useClient(a):a;var K="__MODELENCE_STATE__";function Q(){return typeof document>"u"?false:document.getElementById(K)!==null}function W(){if(typeof document>"u")return null;let t=document.getElementById(K);if(!t)return null;try{return JSON.parse(t.textContent??"")}catch(e){return console.error("Modelence: failed to parse SSR state",e),null}}var v="__modelence_ssr_snapshot__";function I(t){globalThis[v]=t;}function Ve(){return globalThis[v]??null}function q(t){if(typeof window>"u"){I(t);return}let{loadingElement:e,routesElement:r,favicon:o,errorHandler:f,router:g$1}=t;f&&u$1(f),window.addEventListener("unload",()=>{});let k=Q(),y=W();y?.session&&(B(y.session),F());let m=document.getElementById("root"),b=window.location.pathname+window.location.search,h=g$1?g$1({children:r,location:b}):r,O=g()?h:jsx(n,{children:h}),M=jsx(R.StrictMode,{children:jsx(C,{loadingElement:e,children:O})});if(k?E.hydrateRoot(m,M):E.createRoot(m).render(M),o){let T=document.querySelector("link[rel~='icon']");if(T)T.href=o;else {let s=document.createElement("link");s.rel="icon",s.href=o,document.head.appendChild(s);}}}export{c as a,_ as b,Ve as c,q as d,u as e,C as f};//# sourceMappingURL=chunk-YM6DVNYH.js.map
2
+ //# sourceMappingURL=chunk-YM6DVNYH.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/module.ts","../src/system/client.ts","../src/websocket/clientChannel.ts","../src/client.ts","../src/client/renderApp.tsx"],"names":["createClientModule","moduleName","key","getConfig","name","rest","args","callMethod","getArgs","pageParam","systemConfig","ClientChannel","category","onMessage","getWebsocketClientProvider","id","AppProvider","React","SSR_STATE_SCRIPT_ID","hasSsrMarker","readSsrState","node","SNAPSHOT_KEY","setSnapshot","snapshot","_getSsrSnapshot","renderApp","options","loadingElement","routesElement","favicon","errorHandler","router","setErrorHandler","isHydrating","ssrState","hydrateSession","startSessionHeartbeat","container","location","routedTree","appTree","hasConnectedQueryClient","jsx","ModelenceQueryProvider","tree","ReactDOM","link","newLink"],"mappings":"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","file":"chunk-TBGXZXAA.js","sourcesContent":["'use client';\n\nimport type { ObjectId } from 'mongodb';\nimport type { ConfigParams, ConfigType, ValueType } from '../config/types';\nimport { callMethod, type MethodArgs } from './method';\nimport type { AnyMethodShape } from '../methods/types';\n\n// Pulls the config store value without importing server-side code\nimport { getConfig as _getClientConfig } from '../config/client';\n\n// ── type helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Recursively maps ObjectId → string to match the sanitized runtime values\n * sent over the wire. Dates are preserved (revived via typeMap on the client).\n */\ntype Sanitized<T> = T extends ObjectId\n ? string\n : T extends Date\n ? Date\n : T extends (infer U)[]\n ? Sanitized<U>[]\n : T extends object\n ? { [K in keyof T]: Sanitized<T[K]> }\n : T;\n\ntype ExtractArgs<M> = M extends (args: infer A, ...rest: any[]) => any // eslint-disable-line @typescript-eslint/no-explicit-any\n ? A\n : M extends { handler: (args: infer A, ...rest: any[]) => any } // eslint-disable-line @typescript-eslint/no-explicit-any\n ? A\n : MethodArgs;\n\ntype ExtractResult<M> = M extends (...args: any[]) => Promise<infer R> // eslint-disable-line @typescript-eslint/no-explicit-any\n ? Sanitized<R>\n : M extends { handler: (...args: any[]) => Promise<infer R> } // eslint-disable-line @typescript-eslint/no-explicit-any\n ? Sanitized<R>\n : unknown;\n\ntype PublicKeyOf<TSchema extends Record<string, ConfigParams>> = {\n [K in keyof TSchema as TSchema[K] extends ConfigParams<ConfigType, true>\n ? string & K\n : never]: ValueType<TSchema[K]['type']>;\n};\n\ntype AnyModule = {\n name: string;\n configSchema: Record<string, ConfigParams>;\n queries: Record<string, AnyMethodShape>;\n mutations: Record<string, AnyMethodShape>;\n};\n\n// ── createClientModule ────────────────────────────────────────────────────────\n\n/**\n * Creates a typed client accessor for a module's public configs, queries, and mutations.\n *\n * Use `import type` to reference the module so no server code is bundled on the client.\n * Arg and return types for queries and mutations are inferred automatically from the\n * server-side handler signatures.\n *\n * @param moduleName - The module's name as passed to `new Module(name, ...)`.\n *\n * @example\n * ```ts\n * // src/client/payments.ts\n * import type paymentsModule from '../server/payments';\n * import { createClientModule } from 'modelence/client';\n *\n * export const payments = createClientModule<typeof paymentsModule>('payments');\n * ```\n *\n * ```ts\n * // src/components/Checkout.tsx\n * import { useQuery, useMutation } from '@tanstack/react-query';\n * import { payments } from '../client/payments';\n *\n * // Typed config — public keys only, private and secret keys excluded:\n * const currency = payments.getConfig('currency'); // string | undefined\n *\n * // Typed query — pass directly to useQuery:\n * const { data: products } = useQuery(payments.query('getProducts', { page: 1 }));\n *\n * // Typed mutation — pass directly to useMutation:\n * const { mutate: charge } = useMutation(payments.mutation('charge'));\n * charge({ amount: 100 }); // args typed from handler signature\n * ```\n */\nexport function createClientModule<TModule extends AnyModule>(moduleName: string) {\n return {\n getConfig<K extends keyof PublicKeyOf<TModule['configSchema']> & string>(\n key: K\n ): PublicKeyOf<TModule['configSchema']>[K] | undefined {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return _getClientConfig(`${moduleName}.${key}`) as any;\n },\n\n query<K extends keyof TModule['queries'] & string>(\n name: K,\n ...rest: {} extends ExtractArgs<TModule['queries'][K]>\n ? [args?: ExtractArgs<TModule['queries'][K]>]\n : [args: ExtractArgs<TModule['queries'][K]>]\n ) {\n const args = (rest[0] ?? {}) as ExtractArgs<TModule['queries'][K]>;\n return {\n queryKey: [moduleName, name, args] as const,\n queryFn: (): Promise<ExtractResult<TModule['queries'][K]>> =>\n callMethod<ExtractResult<TModule['queries'][K]>>(\n `${moduleName}.${name}`,\n args as MethodArgs\n ),\n };\n },\n\n mutation<K extends keyof TModule['mutations'] & string>(name: K) {\n return {\n mutationFn: (\n args: ExtractArgs<TModule['mutations'][K]>\n ): Promise<ExtractResult<TModule['mutations'][K]>> =>\n callMethod<ExtractResult<TModule['mutations'][K]>>(\n `${moduleName}.${name}`,\n args as MethodArgs\n ),\n };\n },\n\n /**\n * Returns options for `useInfiniteQuery`. The `getArgs` callback receives the\n * current `pageParam` and returns the args to pass to the query handler.\n * Spread the result into `useInfiniteQuery` alongside `getNextPageParam`.\n *\n * Annotate the `pageParam` type in the callback so TypeScript can infer the\n * page param type — no manual generic needed on `useInfiniteQuery`.\n */\n infiniteQuery<K extends keyof TModule['queries'] & string, TPageParam = unknown>(\n name: K,\n getArgs: (pageParam: TPageParam | undefined) => ExtractArgs<TModule['queries'][K]>\n ) {\n return {\n queryKey: [moduleName, name, 'infinite', getArgs(undefined)] as const,\n // Included so TanStack infers TPageParam from the callback type, not from a bare `undefined`.\n initialPageParam: undefined as TPageParam | undefined,\n queryFn: ({\n pageParam,\n }: {\n pageParam: TPageParam | undefined;\n }): Promise<ExtractResult<TModule['queries'][K]>> =>\n callMethod<ExtractResult<TModule['queries'][K]>>(\n `${moduleName}.${name}`,\n getArgs(pageParam) as MethodArgs\n ),\n };\n },\n };\n}\n","import type systemModule from './index';\nimport { createClientModule } from '../client/module';\n\nexport const systemConfig = createClientModule<typeof systemModule>('_system');\n","import { getWebsocketClientProvider } from './client';\n\nexport class ClientChannel<T = unknown> {\n public readonly category: string;\n private readonly onMessage: (data: T) => void;\n\n constructor(category: string, onMessage: (data: T) => void) {\n this.category = category;\n this.onMessage = onMessage;\n }\n\n init() {\n getWebsocketClientProvider()?.on({\n category: this.category,\n listener: this.onMessage,\n });\n }\n\n joinChannel(id: string) {\n getWebsocketClientProvider()?.joinChannel({\n category: this.category,\n id,\n });\n }\n\n leaveChannel(id: string) {\n getWebsocketClientProvider()?.leaveChannel({\n category: this.category,\n id,\n });\n }\n}\n","import React from 'react';\n\nimport { AppProvider as OriginalAppProvider } from './client/AppProvider';\n\nexport { configureClient, type ClientConfig } from './client/clientConfig';\nexport { getConfig } from './config/client';\nexport { createClientModule } from './client/module';\nexport type { ValueType } from './config/types';\nexport { systemConfig } from './system/client';\n\nexport const AppProvider =\n 'useClient' in React\n ? // @ts-ignore: React.useClient only exists in Next.js\n React.useClient(OriginalAppProvider)\n : OriginalAppProvider;\n\nexport { renderApp } from './client/renderApp';\nexport { ModelenceQueryProvider } from './client/queryProvider';\nexport {\n modelenceQuery,\n modelenceLiveQuery,\n modelenceMutation,\n createQueryKey,\n connectModelenceQueryClient,\n disconnectModelenceQueryClient,\n ModelenceQueryClient,\n type ModelenceQueryKey,\n} from './client/query';\nexport { callMethod, MethodError, type MethodArgs, type CallMethodOptions } from './client/method';\nexport { useSession } from './client/session';\nexport {\n signupWithPassword,\n loginWithPassword,\n verifyEmail,\n updateProfile,\n resendEmailVerification,\n logout,\n sendResetPasswordToken,\n resetPassword,\n linkOAuthProvider,\n unlinkOAuthProvider,\n type UserInfo,\n} from './auth/client';\nexport {\n getWebsocketClientProvider,\n setWebsocketClientProvider,\n startWebsockets,\n subscribeLiveQuery,\n} from './websocket/client';\nexport { ClientChannel } from './websocket/clientChannel';\nexport { getLocalStorageSession } from './client/localStorage';\n","import React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport { AppProvider } from '../client';\nimport { setErrorHandler, ErrorHandler } from './errorHandler';\nimport { hydrateSession, startSessionHeartbeat, type SessionInitPayload } from './session';\nimport { ModelenceQueryProvider } from './queryProvider';\nimport { hasConnectedQueryClient } from './query';\n\nconst SSR_STATE_SCRIPT_ID = '__MODELENCE_STATE__';\n\ntype SsrState = {\n session?: SessionInitPayload;\n};\n\nfunction hasSsrMarker(): boolean {\n if (typeof document === 'undefined') {\n return false;\n }\n return document.getElementById(SSR_STATE_SCRIPT_ID) !== null;\n}\n\nfunction readSsrState(): SsrState | null {\n if (typeof document === 'undefined') {\n return null;\n }\n\n const node = document.getElementById(SSR_STATE_SCRIPT_ID);\n if (!node) {\n return null;\n }\n\n try {\n return JSON.parse(node.textContent ?? '') as SsrState;\n } catch (e) {\n // Caller must still hydrate (marker presence drives that, not parsed payload).\n console.error('Modelence: failed to parse SSR state', e);\n return null;\n }\n}\n\nexport type SsrRouter = (props: {\n children: React.ReactNode;\n location?: string;\n}) => React.ReactElement;\n\nexport interface RenderAppOptions {\n loadingElement: React.ReactNode;\n routesElement: React.ReactNode;\n favicon?: string;\n errorHandler?: ErrorHandler;\n router?: SsrRouter;\n}\n\n// Shared via globalThis: ssrLoadModule loads the user's entry in a separate\n// module graph from the framework runtime.\nconst SNAPSHOT_KEY = '__modelence_ssr_snapshot__';\n\ntype GlobalWithSnapshot = typeof globalThis & {\n [SNAPSHOT_KEY]?: RenderAppOptions | null;\n};\n\nfunction setSnapshot(snapshot: RenderAppOptions | null) {\n (globalThis as GlobalWithSnapshot)[SNAPSHOT_KEY] = snapshot;\n}\n\n/** @internal Used by the SSR runtime after evaluating the user's entry. */\nexport function _getSsrSnapshot(): RenderAppOptions | null {\n return (globalThis as GlobalWithSnapshot)[SNAPSHOT_KEY] ?? null;\n}\n\nexport function renderApp(options: RenderAppOptions) {\n if (typeof window === 'undefined') {\n setSnapshot(options);\n return;\n }\n\n const { loadingElement, routesElement, favicon, errorHandler, router } = options;\n\n if (errorHandler) {\n setErrorHandler(errorHandler);\n }\n\n // Empty 'unload' handler prevents bfcache in most browsers.\n window.addEventListener('unload', () => {});\n\n // Hydrate session BEFORE building the tree so `isSessionInitialized()` is\n // true on the first render and matches the server output. Hydration mode\n // tracks marker presence (not parse success): a parse failure still leaves\n // server-rendered DOM that must be hydrated, not replaced.\n const isHydrating = hasSsrMarker();\n const ssrState = readSsrState();\n if (ssrState?.session) {\n hydrateSession(ssrState.session);\n // Fire-and-forget: the heartbeat loop runs in the background.\n void startSessionHeartbeat();\n }\n\n const container = document.getElementById('root')!;\n // Pass the same location the server used (req.originalUrl == path + search;\n // the hash is never sent to the server) so a location-driven router (e.g. a\n // static router) resolves the same route on hydration as it did during SSR,\n // avoiding hydration mismatches.\n const location = window.location.pathname + window.location.search;\n const routedTree = router ? router({ children: routesElement, location }) : routesElement;\n\n // If the app already connected its own QueryClient (the documented\n // bring-your-own-provider pattern connects before calling renderApp), don't\n // inject ours. A second provider would shadow the user's client: useQuery\n // would read the inner client while live-query updates write to the outer\n // one, so real-time queries would never update.\n const appTree = hasConnectedQueryClient() ? (\n routedTree\n ) : (\n <ModelenceQueryProvider>{routedTree}</ModelenceQueryProvider>\n );\n\n const tree = (\n <React.StrictMode>\n <AppProvider loadingElement={loadingElement}>{appTree}</AppProvider>\n </React.StrictMode>\n );\n\n if (isHydrating) {\n ReactDOM.hydrateRoot(container, tree);\n } else {\n ReactDOM.createRoot(container).render(tree);\n }\n\n if (favicon) {\n const link = document.querySelector(\"link[rel~='icon']\") as HTMLLinkElement;\n if (!link) {\n const newLink = document.createElement('link');\n newLink.rel = 'icon';\n newLink.href = favicon;\n document.head.appendChild(newLink);\n } else {\n link.href = favicon;\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/client/module.ts","../src/system/client.ts","../src/websocket/clientChannel.ts","../src/client.ts","../src/client/renderApp.tsx"],"names":["createClientModule","moduleName","key","getConfig","name","rest","args","callMethod","getArgs","pageParam","systemConfig","ClientChannel","category","onMessage","getWebsocketClientProvider","id","AppProvider","React","SSR_STATE_SCRIPT_ID","hasSsrMarker","readSsrState","node","SNAPSHOT_KEY","setSnapshot","snapshot","_getSsrSnapshot","renderApp","options","loadingElement","routesElement","favicon","errorHandler","router","setErrorHandler","isHydrating","ssrState","hydrateSession","startSessionHeartbeat","container","location","routedTree","appTree","hasConnectedQueryClient","jsx","ModelenceQueryProvider","tree","ReactDOM","link","newLink"],"mappings":"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","file":"chunk-YM6DVNYH.js","sourcesContent":["'use client';\n\nimport type { ObjectId } from 'mongodb';\nimport type { ConfigParams, ConfigType, ValueType } from '../config/types';\nimport { callMethod, type MethodArgs } from './method';\nimport type { AnyMethodShape } from '../methods/types';\n\n// Pulls the config store value without importing server-side code\nimport { getConfig as _getClientConfig } from '../config/client';\n\n// ── type helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Recursively maps ObjectId → string to match the sanitized runtime values\n * sent over the wire. Dates are preserved (revived via typeMap on the client).\n */\ntype Sanitized<T> = T extends ObjectId\n ? string\n : T extends Date\n ? Date\n : T extends (infer U)[]\n ? Sanitized<U>[]\n : T extends object\n ? { [K in keyof T]: Sanitized<T[K]> }\n : T;\n\ntype ExtractArgs<M> = M extends (args: infer A, ...rest: any[]) => any // eslint-disable-line @typescript-eslint/no-explicit-any\n ? A\n : M extends { handler: (args: infer A, ...rest: any[]) => any } // eslint-disable-line @typescript-eslint/no-explicit-any\n ? A\n : MethodArgs;\n\ntype ExtractResult<M> = M extends (...args: any[]) => Promise<infer R> // eslint-disable-line @typescript-eslint/no-explicit-any\n ? Sanitized<R>\n : M extends { handler: (...args: any[]) => Promise<infer R> } // eslint-disable-line @typescript-eslint/no-explicit-any\n ? Sanitized<R>\n : unknown;\n\ntype PublicKeyOf<TSchema extends Record<string, ConfigParams>> = {\n [K in keyof TSchema as TSchema[K] extends ConfigParams<ConfigType, true>\n ? string & K\n : never]: ValueType<TSchema[K]['type']>;\n};\n\ntype AnyModule = {\n name: string;\n configSchema: Record<string, ConfigParams>;\n queries: Record<string, AnyMethodShape>;\n mutations: Record<string, AnyMethodShape>;\n};\n\n// ── createClientModule ────────────────────────────────────────────────────────\n\n/**\n * Creates a typed client accessor for a module's public configs, queries, and mutations.\n *\n * Use `import type` to reference the module so no server code is bundled on the client.\n * Arg and return types for queries and mutations are inferred automatically from the\n * server-side handler signatures.\n *\n * @param moduleName - The module's name as passed to `new Module(name, ...)`.\n *\n * @example\n * ```ts\n * // src/client/payments.ts\n * import type paymentsModule from '../server/payments';\n * import { createClientModule } from 'modelence/client';\n *\n * export const payments = createClientModule<typeof paymentsModule>('payments');\n * ```\n *\n * ```ts\n * // src/components/Checkout.tsx\n * import { useQuery, useMutation } from '@tanstack/react-query';\n * import { payments } from '../client/payments';\n *\n * // Typed config — public keys only, private and secret keys excluded:\n * const currency = payments.getConfig('currency'); // string | undefined\n *\n * // Typed query — pass directly to useQuery:\n * const { data: products } = useQuery(payments.query('getProducts', { page: 1 }));\n *\n * // Typed mutation — pass directly to useMutation:\n * const { mutate: charge } = useMutation(payments.mutation('charge'));\n * charge({ amount: 100 }); // args typed from handler signature\n * ```\n */\nexport function createClientModule<TModule extends AnyModule>(moduleName: string) {\n return {\n getConfig<K extends keyof PublicKeyOf<TModule['configSchema']> & string>(\n key: K\n ): PublicKeyOf<TModule['configSchema']>[K] | undefined {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return _getClientConfig(`${moduleName}.${key}`) as any;\n },\n\n query<K extends keyof TModule['queries'] & string>(\n name: K,\n ...rest: {} extends ExtractArgs<TModule['queries'][K]>\n ? [args?: ExtractArgs<TModule['queries'][K]>]\n : [args: ExtractArgs<TModule['queries'][K]>]\n ) {\n const args = (rest[0] ?? {}) as ExtractArgs<TModule['queries'][K]>;\n return {\n queryKey: [moduleName, name, args] as const,\n queryFn: (): Promise<ExtractResult<TModule['queries'][K]>> =>\n callMethod<ExtractResult<TModule['queries'][K]>>(\n `${moduleName}.${name}`,\n args as MethodArgs\n ),\n };\n },\n\n mutation<K extends keyof TModule['mutations'] & string>(name: K) {\n return {\n mutationFn: (\n args: ExtractArgs<TModule['mutations'][K]>\n ): Promise<ExtractResult<TModule['mutations'][K]>> =>\n callMethod<ExtractResult<TModule['mutations'][K]>>(\n `${moduleName}.${name}`,\n args as MethodArgs\n ),\n };\n },\n\n /**\n * Returns options for `useInfiniteQuery`. The `getArgs` callback receives the\n * current `pageParam` and returns the args to pass to the query handler.\n * Spread the result into `useInfiniteQuery` alongside `getNextPageParam`.\n *\n * Annotate the `pageParam` type in the callback so TypeScript can infer the\n * page param type — no manual generic needed on `useInfiniteQuery`.\n */\n infiniteQuery<K extends keyof TModule['queries'] & string, TPageParam = unknown>(\n name: K,\n getArgs: (pageParam: TPageParam | undefined) => ExtractArgs<TModule['queries'][K]>\n ) {\n return {\n queryKey: [moduleName, name, 'infinite', getArgs(undefined)] as const,\n // Included so TanStack infers TPageParam from the callback type, not from a bare `undefined`.\n initialPageParam: undefined as TPageParam | undefined,\n queryFn: ({\n pageParam,\n }: {\n pageParam: TPageParam | undefined;\n }): Promise<ExtractResult<TModule['queries'][K]>> =>\n callMethod<ExtractResult<TModule['queries'][K]>>(\n `${moduleName}.${name}`,\n getArgs(pageParam) as MethodArgs\n ),\n };\n },\n };\n}\n","import type systemModule from './index';\nimport { createClientModule } from '../client/module';\n\nexport const systemConfig = createClientModule<typeof systemModule>('_system');\n","import { getWebsocketClientProvider } from './client';\n\nexport class ClientChannel<T = unknown> {\n public readonly category: string;\n private readonly onMessage: (data: T) => void;\n\n constructor(category: string, onMessage: (data: T) => void) {\n this.category = category;\n this.onMessage = onMessage;\n }\n\n init() {\n getWebsocketClientProvider()?.on({\n category: this.category,\n listener: this.onMessage,\n });\n }\n\n joinChannel(id: string) {\n getWebsocketClientProvider()?.joinChannel({\n category: this.category,\n id,\n });\n }\n\n leaveChannel(id: string) {\n getWebsocketClientProvider()?.leaveChannel({\n category: this.category,\n id,\n });\n }\n}\n","import React from 'react';\n\nimport { AppProvider as OriginalAppProvider } from './client/AppProvider';\n\nexport { configureClient, type ClientConfig } from './client/clientConfig';\nexport { getConfig } from './config/client';\nexport { createClientModule } from './client/module';\nexport type { ValueType } from './config/types';\nexport { systemConfig } from './system/client';\n\nexport const AppProvider =\n 'useClient' in React\n ? // @ts-ignore: React.useClient only exists in Next.js\n React.useClient(OriginalAppProvider)\n : OriginalAppProvider;\n\nexport { renderApp } from './client/renderApp';\nexport { ModelenceQueryProvider } from './client/queryProvider';\nexport {\n modelenceQuery,\n modelenceLiveQuery,\n modelenceMutation,\n createQueryKey,\n connectModelenceQueryClient,\n disconnectModelenceQueryClient,\n ModelenceQueryClient,\n type ModelenceQueryKey,\n} from './client/query';\nexport { callMethod, MethodError, type MethodArgs, type CallMethodOptions } from './client/method';\nexport { useSession } from './client/session';\nexport {\n signupWithPassword,\n loginWithPassword,\n verifyEmail,\n updateProfile,\n resendEmailVerification,\n logout,\n sendResetPasswordToken,\n resetPassword,\n sendMagicLink,\n loginWithMagicLink,\n loginWithOneTimeCode,\n signInWithOAuth,\n loginWithOAuth,\n linkOAuthProvider,\n unlinkOAuthProvider,\n type UserInfo,\n} from './auth/client';\nexport {\n getWebsocketClientProvider,\n setWebsocketClientProvider,\n startWebsockets,\n subscribeLiveQuery,\n} from './websocket/client';\nexport { ClientChannel } from './websocket/clientChannel';\nexport { getLocalStorageSession } from './client/localStorage';\n","import React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport { AppProvider } from '../client';\nimport { setErrorHandler, ErrorHandler } from './errorHandler';\nimport { hydrateSession, startSessionHeartbeat, type SessionInitPayload } from './session';\nimport { ModelenceQueryProvider } from './queryProvider';\nimport { hasConnectedQueryClient } from './query';\n\nconst SSR_STATE_SCRIPT_ID = '__MODELENCE_STATE__';\n\ntype SsrState = {\n session?: SessionInitPayload;\n};\n\nfunction hasSsrMarker(): boolean {\n if (typeof document === 'undefined') {\n return false;\n }\n return document.getElementById(SSR_STATE_SCRIPT_ID) !== null;\n}\n\nfunction readSsrState(): SsrState | null {\n if (typeof document === 'undefined') {\n return null;\n }\n\n const node = document.getElementById(SSR_STATE_SCRIPT_ID);\n if (!node) {\n return null;\n }\n\n try {\n return JSON.parse(node.textContent ?? '') as SsrState;\n } catch (e) {\n // Caller must still hydrate (marker presence drives that, not parsed payload).\n console.error('Modelence: failed to parse SSR state', e);\n return null;\n }\n}\n\nexport type SsrRouter = (props: {\n children: React.ReactNode;\n location?: string;\n}) => React.ReactElement;\n\nexport interface RenderAppOptions {\n loadingElement: React.ReactNode;\n routesElement: React.ReactNode;\n favicon?: string;\n errorHandler?: ErrorHandler;\n router?: SsrRouter;\n}\n\n// Shared via globalThis: ssrLoadModule loads the user's entry in a separate\n// module graph from the framework runtime.\nconst SNAPSHOT_KEY = '__modelence_ssr_snapshot__';\n\ntype GlobalWithSnapshot = typeof globalThis & {\n [SNAPSHOT_KEY]?: RenderAppOptions | null;\n};\n\nfunction setSnapshot(snapshot: RenderAppOptions | null) {\n (globalThis as GlobalWithSnapshot)[SNAPSHOT_KEY] = snapshot;\n}\n\n/** @internal Used by the SSR runtime after evaluating the user's entry. */\nexport function _getSsrSnapshot(): RenderAppOptions | null {\n return (globalThis as GlobalWithSnapshot)[SNAPSHOT_KEY] ?? null;\n}\n\nexport function renderApp(options: RenderAppOptions) {\n if (typeof window === 'undefined') {\n setSnapshot(options);\n return;\n }\n\n const { loadingElement, routesElement, favicon, errorHandler, router } = options;\n\n if (errorHandler) {\n setErrorHandler(errorHandler);\n }\n\n // Empty 'unload' handler prevents bfcache in most browsers.\n window.addEventListener('unload', () => {});\n\n // Hydrate session BEFORE building the tree so `isSessionInitialized()` is\n // true on the first render and matches the server output. Hydration mode\n // tracks marker presence (not parse success): a parse failure still leaves\n // server-rendered DOM that must be hydrated, not replaced.\n const isHydrating = hasSsrMarker();\n const ssrState = readSsrState();\n if (ssrState?.session) {\n hydrateSession(ssrState.session);\n // Fire-and-forget: the heartbeat loop runs in the background.\n void startSessionHeartbeat();\n }\n\n const container = document.getElementById('root')!;\n // Pass the same location the server used (req.originalUrl == path + search;\n // the hash is never sent to the server) so a location-driven router (e.g. a\n // static router) resolves the same route on hydration as it did during SSR,\n // avoiding hydration mismatches.\n const location = window.location.pathname + window.location.search;\n const routedTree = router ? router({ children: routesElement, location }) : routesElement;\n\n // If the app already connected its own QueryClient (the documented\n // bring-your-own-provider pattern connects before calling renderApp), don't\n // inject ours. A second provider would shadow the user's client: useQuery\n // would read the inner client while live-query updates write to the outer\n // one, so real-time queries would never update.\n const appTree = hasConnectedQueryClient() ? (\n routedTree\n ) : (\n <ModelenceQueryProvider>{routedTree}</ModelenceQueryProvider>\n );\n\n const tree = (\n <React.StrictMode>\n <AppProvider loadingElement={loadingElement}>{appTree}</AppProvider>\n </React.StrictMode>\n );\n\n if (isHydrating) {\n ReactDOM.hydrateRoot(container, tree);\n } else {\n ReactDOM.createRoot(container).render(tree);\n }\n\n if (favicon) {\n const link = document.querySelector(\"link[rel~='icon']\") as HTMLLinkElement;\n if (!link) {\n const newLink = document.createElement('link');\n newLink.rel = 'icon';\n newLink.href = favicon;\n document.head.appendChild(newLink);\n } else {\n link.href = favicon;\n }\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import {G as G$1,t,s,y as y$1,D,C,E,c as c$1}from'./chunk-BJWGBMNX.js';import {c}from'./chunk-5M6FUMUK.js';import {useState,useEffect}from'react';import {jsx}from'react/jsx-runtime';import $ from'socket.io-client';import {hashKey,QueryClient,QueryClientProvider,HydrationBoundary}from'@tanstack/react-query';var K="__MODELENCE_STATE__",R=false;function N(){return typeof document<"u"&&document.getElementById(K)!==null}function le({children:e,loadingElement:n}){let r=typeof window>"u",[t,o]=useState(()=>!r&&!G$1()&&!N());return useEffect(()=>{async function s(){if(!R){if(R=true,G$1()){D()&&await C();return}await E(),o(false);}}s();},[]),t?n??jsx("div",{children:"Loading..."}):e}var y=null,v=new Map;function p(){if(!y)throw new Error("WebSocket not initialized. Call startWebsockets() first.");return y}function B(){let e=s(),n=t();for(let r of v.values())y?.emit("subscribeLiveQuery",{subscriptionId:r.subscriptionId,method:r.method,args:r.args,authToken:e,clientInfo:n});}function F(e){let n=c$1()?.baseUrl??"/";y=$(n,{transports:["websocket"],auth:{token:s()}}),y.on("connect",()=>{v.size>0&&(console.log(`[Modelence] WebSocket reconnected, re-subscribing to ${v.size} live queries`),B());}),e.channels?.forEach(r=>r.init());}function j({category:e,listener:n}){p().on(e,n);}function H({category:e,listener:n}){p().once(e,n);}function Y({category:e,listener:n}){p().off(e,n);}function k({eventName:e,category:n,id:r}){p().emit(e,`${n}:${r}`);}function J({category:e,id:n}){k({eventName:"joinChannel",category:e,id:n});}function G({category:e,id:n}){k({eventName:"leaveChannel",category:e,id:n});}var V=0;function S(e,n,r,t$1){let o=`sub-${++V}-${Date.now()}`,s$1=({subscriptionId:l,data:i,typeMap:f})=>{l===o&&r(c(i,f));},a=({subscriptionId:l,error:i})=>{l===o&&(console.error(`[Modelence] Live query error for ${e}:`,i),t$1?.(i));},c$1=p();return c$1.on("liveQueryData",s$1),c$1.on("liveQueryError",a),v.set(o,{subscriptionId:o,method:e,args:n}),c$1.connected&&c$1.emit("subscribeLiveQuery",{subscriptionId:o,method:e,args:n,authToken:s(),clientInfo:t()}),()=>{v.delete(o),c$1.emit("unsubscribeLiveQuery",{subscriptionId:o}),c$1.off("liveQueryData",s$1),c$1.off("liveQueryError",a);}}var X={init:F,on:j,once:H,off:Y,emit:k,joinChannel:J,leaveChannel:G},A=X;var w=null;function _(e){w=e;}function Ce(){return w}function L(e){if(w){console.warn("WebSocket already initialized. Skipping initialization.");return}let n=e?.provider||A;_(n);try{n.init({channels:e?.channels});}catch(r){throw _(null),r}}var d=null,g=null,Q=false,u=new Map;function T(e){d!==e&&(d&&Z(),d=e,g=e.getQueryCache().subscribe(n=>{if(n.type==="removed"){let r=hashKey(n.query.queryKey),t=u.get(r);if(t){if(t.resolvers.size>0){let o=new Error("Query was removed from cache");t.resolvers.forEach(s=>s.reject(o)),t.resolvers.clear();}t.unsubscribe(),u.delete(r);}}}));}function Te(){return d!==null}function Z(){g&&(g(),g=null),u.forEach(e=>e.unsubscribe()),u.clear(),d=null,Q=false;}var W=class{connect(n){T(n);}};function Ee(e,n={}){return {queryKey:[e,n],queryFn:()=>y$1(e,n)}}function Pe(e,n={}){let r=["live",e,n],t=hashKey(r);return {queryKey:r,queryFn:()=>new Promise((o,s)=>{if(typeof window>"u")return;if(!d){let c=new Error("Modelence: connect a QueryClient before using modelenceLiveQuery(). Mount <ModelenceQueryProvider> or call connectModelenceQueryClient().");console.error("[Modelence]",c.message),s(c);return}Q||(L(),Q=true);let a=u.get(t);a||(a={unsubscribe:S(e,n,l=>{let i=u.get(t);i?.resolvers.size&&(i.resolvers.forEach(f=>f.resolve(l)),i.resolvers.clear()),d&&d.setQueryData(r,l);},l=>{let i=u.get(t);i&&(i.resolvers.size&&(i.resolvers.forEach(f=>f.reject(new Error(l))),i.resolvers.clear()),i.unsubscribe(),u.delete(t));}),resolvers:new Set},u.set(t,a)),a.resolvers.add({resolve:o,reject:s});}),staleTime:1/0,refetchOnWindowFocus:false,refetchOnMount:false,refetchOnReconnect:false,gcTime:0}}function Me(e,n={}){return {mutationFn:(r={})=>y$1(e,{...n,...r})}}function xe(e,n={}){return [e,n]}var oe="__MODELENCE_QUERY_STATE__";function ie(){if(typeof document>"u")return;let e=document.getElementById(oe);if(!(!e||!e.textContent))try{return JSON.parse(e.textContent)}catch(n){console.error("Modelence: failed to parse SSR query state",n);return}}function Le({children:e,client:n,dehydratedState:r}){let[t]=useState(()=>{let s=n??new QueryClient({defaultOptions:{queries:{staleTime:6e4}}});return typeof window<"u"&&T(s),s}),o=r??ie();return jsx(QueryClientProvider,{client:t,children:jsx(HydrationBoundary,{state:o,children:e})})}export{le as a,S as b,_ as c,Ce as d,L as e,T as f,Te as g,Z as h,W as i,Ee as j,Pe as k,Me as l,xe as m,Le as n};//# sourceMappingURL=chunk-ZEXT732Q.js.map
2
+ //# sourceMappingURL=chunk-ZEXT732Q.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client/AppProvider.tsx","../src/websocket/socketio/client.ts","../src/websocket/client.ts","../src/client/query.ts","../src/client/queryProvider.tsx"],"names":["SSR_STATE_SCRIPT_ID","isInitialized","hasServerRenderedMarkup","AppProvider","children","loadingElement","isServer","isLoading","setIsLoading","useState","isSessionInitialized","useEffect","initConfig","_isReconciliationPending","reconcileSession","initSession","jsx","socketClient","activeLiveSubscriptions","getSocket","resubscribeAll","authToken","getAuthToken","clientInfo","getClientInfo","sub","init","props","baseUrl","getClientConfig","io","channel","on","category","listener","once","off","emit","eventName","id","joinChannel","leaveChannel","liveQueryCounter","subscribeLiveQuery","method","args","onData","onError","subscriptionId","handleData","sid","data","typeMap","reviveResponseTypes","handleError","error","socket","websocketProvider","client_default","websocketClientProvider","setWebsocketClientProvider","provider","getWebsocketClientProvider","startWebsockets","queryClientRef","cacheUnsubscribe","websocketsStarted","subscriptions","connectModelenceQueryClient","queryClient","disconnectModelenceQueryClient","event","subscriptionKey","hashKey","cancelError","r","hasConnectedQueryClient","ModelenceQueryClient","modelenceQuery","methodName","callMethod","modelenceLiveQuery","queryKey","resolve","reject","currentSub","modelenceMutation","defaultArgs","variables","createQueryKey","SSR_QUERY_STATE_SCRIPT_ID","readDehydratedState","node","e","ModelenceQueryProvider","client","dehydratedState","internalClient","qc","QueryClient","state","QueryClientProvider","HydrationBoundary"],"mappings":"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","file":"chunk-ZEXT732Q.js","sourcesContent":["/*\n The \"use client\" directive is specifically for the Next.js layout component, which is rendered on the server by default.\n Because of this, we are explicitly marking it as a client component, so we can render this component on the client\n and properly initialize config on the client side.\n\n While this is specific to Next.js, it is simply ignored outside of Next.js and should not cause errors.\n*/\n'use client';\n\nimport { useState, useEffect, ReactNode } from 'react';\nimport {\n _isReconciliationPending,\n initSession,\n isSessionInitialized,\n reconcileSession,\n} from './session';\n\nconst SSR_STATE_SCRIPT_ID = '__MODELENCE_STATE__';\n\ninterface AppProviderProps {\n children: ReactNode;\n loadingElement?: ReactNode;\n}\n\nlet isInitialized = false;\n\n// Presence of the state script signals server-rendered markup in the DOM,\n// even if `hydrateSession` failed to parse it. Hiding under a loading shell\n// here would cause a hydration mismatch and a flash-of-spinner.\nfunction hasServerRenderedMarkup(): boolean {\n return typeof document !== 'undefined' && document.getElementById(SSR_STATE_SCRIPT_ID) !== null;\n}\n\nexport function AppProvider({ children, loadingElement }: AppProviderProps) {\n const isServer = typeof window === 'undefined';\n const [isLoading, setIsLoading] = useState(\n () => !isServer && !isSessionInitialized() && !hasServerRenderedMarkup()\n );\n\n useEffect(() => {\n async function initConfig() {\n if (isInitialized) {\n return;\n }\n\n isInitialized = true;\n\n if (isSessionInitialized()) {\n // SSR couldn't authenticate via cookie; reconcile via body token now.\n if (_isReconciliationPending()) {\n await reconcileSession();\n }\n return;\n }\n\n await initSession();\n setIsLoading(false);\n }\n\n void initConfig();\n }, []);\n\n if (isLoading) {\n return loadingElement ?? <div>Loading...</div>;\n }\n\n return children;\n}\n","import io, { Socket } from 'socket.io-client';\nimport { WebsocketClientProvider } from '../types';\nimport { ClientChannel } from '../clientChannel';\nimport { getAuthToken, getClientInfo } from '@/auth/client';\nimport { getClientConfig } from '@/client/clientConfig';\nimport { reviveResponseTypes } from '@/methods/serialize';\n\nlet socketClient: Socket | null = null;\n\ninterface ActiveLiveSubscription {\n subscriptionId: string;\n method: string;\n args: Record<string, unknown>;\n}\nconst activeLiveSubscriptions = new Map<string, ActiveLiveSubscription>();\n\nfunction getSocket(): Socket {\n if (!socketClient) {\n throw new Error('WebSocket not initialized. Call startWebsockets() first.');\n }\n return socketClient;\n}\n\nfunction resubscribeAll() {\n const authToken = getAuthToken();\n const clientInfo = getClientInfo();\n for (const sub of activeLiveSubscriptions.values()) {\n socketClient?.emit('subscribeLiveQuery', {\n subscriptionId: sub.subscriptionId,\n method: sub.method,\n args: sub.args,\n authToken,\n clientInfo,\n });\n }\n}\n\nfunction init(props: { channels?: ClientChannel<unknown>[] }) {\n const baseUrl = getClientConfig()?.baseUrl ?? '/';\n socketClient = io(baseUrl, {\n transports: ['websocket'],\n auth: {\n token: getAuthToken(),\n },\n });\n\n // Subscribe to all live queries on connect/reconnect\n socketClient.on('connect', () => {\n if (activeLiveSubscriptions.size > 0) {\n console.log(\n `[Modelence] WebSocket reconnected, re-subscribing to ${activeLiveSubscriptions.size} live queries`\n );\n resubscribeAll();\n }\n });\n\n props.channels?.forEach((channel) => channel.init());\n}\n\nfunction on<T = unknown>({\n category,\n listener,\n}: {\n category: string;\n listener: (data: T) => void;\n}) {\n getSocket().on(category, listener);\n}\n\nfunction once<T = unknown>({\n category,\n listener,\n}: {\n category: string;\n listener: (data: T) => void;\n}) {\n getSocket().once(category, listener);\n}\n\nfunction off<T = unknown>({\n category,\n listener,\n}: {\n category: string;\n listener: (data: T) => void;\n}) {\n getSocket().off(category, listener);\n}\n\nfunction emit({ eventName, category, id }: { eventName: string; category: string; id: string }) {\n getSocket().emit(eventName, `${category}:${id}`);\n}\n\nfunction joinChannel({ category, id }: { category: string; id: string }) {\n emit({\n eventName: 'joinChannel',\n category,\n id,\n });\n}\n\nfunction leaveChannel({ category, id }: { category: string; id: string }) {\n emit({\n eventName: 'leaveChannel',\n category,\n id,\n });\n}\n\nlet liveQueryCounter = 0;\n\nexport function subscribeLiveQuery<T = unknown>(\n method: string,\n args: Record<string, unknown>,\n onData: (data: T) => void,\n onError?: (error: string) => void\n): () => void {\n const subscriptionId = `sub-${++liveQueryCounter}-${Date.now()}`;\n\n const handleData = ({\n subscriptionId: sid,\n data,\n typeMap,\n }: {\n subscriptionId: string;\n data: T;\n typeMap?: Record<string, unknown>;\n }) => {\n if (sid === subscriptionId) {\n onData(reviveResponseTypes(data, typeMap));\n }\n };\n\n const handleError = ({\n subscriptionId: sid,\n error,\n }: {\n subscriptionId: string;\n error: string;\n }) => {\n if (sid === subscriptionId) {\n console.error(`[Modelence] Live query error for ${method}:`, error);\n onError?.(error);\n }\n };\n\n const socket = getSocket();\n socket.on('liveQueryData', handleData);\n socket.on('liveQueryError', handleError);\n\n activeLiveSubscriptions.set(subscriptionId, { subscriptionId, method, args });\n\n // Only emit if already connected; otherwise the connect handler will handle it\n if (socket.connected) {\n socket.emit('subscribeLiveQuery', {\n subscriptionId,\n method,\n args,\n authToken: getAuthToken(),\n clientInfo: getClientInfo(),\n });\n }\n\n // Return unsubscribe function\n return () => {\n activeLiveSubscriptions.delete(subscriptionId);\n socket.emit('unsubscribeLiveQuery', { subscriptionId });\n socket.off('liveQueryData', handleData);\n socket.off('liveQueryError', handleError);\n };\n}\n\nconst websocketProvider: WebsocketClientProvider = {\n init,\n on,\n once,\n off,\n emit,\n joinChannel,\n leaveChannel,\n};\n\nexport default websocketProvider;\n","import { ClientChannel } from './clientChannel';\nimport websocketProvider, { subscribeLiveQuery } from './socketio/client';\nimport { WebsocketClientProvider } from './types';\n\nexport { subscribeLiveQuery };\n\nlet websocketClientProvider: WebsocketClientProvider | null = null;\n\nexport function setWebsocketClientProvider(provider: WebsocketClientProvider | null) {\n websocketClientProvider = provider;\n}\n\nexport function getWebsocketClientProvider() {\n return websocketClientProvider;\n}\n\nexport function startWebsockets(props?: {\n provider?: WebsocketClientProvider;\n channels?: ClientChannel[];\n}) {\n if (websocketClientProvider) {\n console.warn('WebSocket already initialized. Skipping initialization.');\n return;\n }\n\n const provider = props?.provider || websocketProvider;\n setWebsocketClientProvider(provider);\n try {\n provider.init({\n channels: props?.channels,\n });\n } catch (error) {\n setWebsocketClientProvider(null);\n throw error;\n }\n}\n","'use client';\n\nimport { QueryClient, hashKey } from '@tanstack/react-query';\nimport { callMethod } from './method';\nimport { startWebsockets, subscribeLiveQuery } from '../websocket/client';\n\ntype Args = Record<string, unknown>;\n\ninterface Subscription {\n unsubscribe: () => void;\n resolvers: Set<{\n resolve: (data: unknown) => void;\n reject: (error: Error) => void;\n }>;\n}\n\nlet queryClientRef: QueryClient | null = null;\nlet cacheUnsubscribe: (() => void) | null = null;\nlet websocketsStarted = false;\nconst subscriptions = new Map<string, Subscription>();\n\n/**\n * Connects a `QueryClient` to Modelence's live-query layer. Auto-called by\n * `<ModelenceQueryProvider>`; only call manually if you mount your own\n * `<QueryClientProvider>`.\n *\n * Note: WebSocket setup is deferred until the first `modelenceLiveQuery`\n * call, so apps that only use `modelenceQuery`/`modelenceMutation` never\n * open a socket.\n */\nexport function connectModelenceQueryClient(queryClient: QueryClient) {\n if (queryClientRef === queryClient) {\n return;\n }\n\n if (queryClientRef) {\n disconnectModelenceQueryClient();\n }\n\n queryClientRef = queryClient;\n\n cacheUnsubscribe = queryClient.getQueryCache().subscribe((event) => {\n if (event.type === 'removed') {\n const subscriptionKey = hashKey(event.query.queryKey);\n const sub = subscriptions.get(subscriptionKey);\n if (sub) {\n if (sub.resolvers.size > 0) {\n const cancelError = new Error('Query was removed from cache');\n sub.resolvers.forEach((r) => r.reject(cancelError));\n sub.resolvers.clear();\n }\n sub.unsubscribe();\n subscriptions.delete(subscriptionKey);\n }\n }\n });\n}\n\n/**\n * Whether a `QueryClient` is already connected to the live-query layer.\n * `renderApp` uses this to avoid injecting its own `<ModelenceQueryProvider>`\n * when the app already mounts its own provider and connects it beforehand.\n */\nexport function hasConnectedQueryClient(): boolean {\n return queryClientRef !== null;\n}\n\nexport function disconnectModelenceQueryClient() {\n if (cacheUnsubscribe) {\n cacheUnsubscribe();\n cacheUnsubscribe = null;\n }\n subscriptions.forEach((sub) => sub.unsubscribe());\n subscriptions.clear();\n queryClientRef = null;\n websocketsStarted = false;\n}\n\n/** @deprecated Use `connectModelenceQueryClient(queryClient)` instead. */\nexport class ModelenceQueryClient {\n connect(queryClient: QueryClient) {\n connectModelenceQueryClient(queryClient);\n }\n}\n\n/**\n * @example\n * ```tsx\n * const { data } = useQuery(modelenceQuery('todo.getAll'));\n * ```\n */\nexport function modelenceQuery<T = unknown>(methodName: string, args: Args = {}) {\n return {\n queryKey: [methodName, args],\n queryFn: () => callMethod<T>(methodName, args),\n };\n}\n\n/**\n * Live query — data updates in real time as the underlying collection changes.\n * Requires a `QueryClient` connected via `<ModelenceQueryProvider>` or\n * `connectModelenceQueryClient(...)`.\n */\nexport function modelenceLiveQuery<T = unknown>(methodName: string, args: Args = {}) {\n const queryKey = ['live', methodName, args] as const;\n const subscriptionKey = hashKey(queryKey);\n\n return {\n queryKey,\n queryFn: () =>\n new Promise<T>((resolve, reject) => {\n // Live queries are WebSocket subscriptions — no server snapshot. Stay\n // pending on the server so Suspense renders; client re-runs after hydration.\n if (typeof window === 'undefined') {\n return;\n }\n\n if (!queryClientRef) {\n const error = new Error(\n 'Modelence: connect a QueryClient before using modelenceLiveQuery(). Mount <ModelenceQueryProvider> or call connectModelenceQueryClient().'\n );\n console.error('[Modelence]', error.message);\n reject(error);\n return;\n }\n\n if (!websocketsStarted) {\n startWebsockets();\n websocketsStarted = true;\n }\n\n let sub = subscriptions.get(subscriptionKey);\n\n if (!sub) {\n const unsubscribe = subscribeLiveQuery<T>(\n methodName,\n args,\n (data) => {\n const currentSub = subscriptions.get(subscriptionKey);\n\n if (currentSub?.resolvers.size) {\n currentSub.resolvers.forEach((r) => r.resolve(data));\n currentSub.resolvers.clear();\n }\n\n if (queryClientRef) {\n queryClientRef.setQueryData(queryKey, data);\n }\n },\n (error) => {\n const currentSub = subscriptions.get(subscriptionKey);\n if (currentSub) {\n if (currentSub.resolvers.size) {\n currentSub.resolvers.forEach((r) => r.reject(new Error(error)));\n currentSub.resolvers.clear();\n }\n currentSub.unsubscribe();\n subscriptions.delete(subscriptionKey);\n }\n }\n );\n\n sub = { unsubscribe, resolvers: new Set() };\n subscriptions.set(subscriptionKey, sub);\n }\n\n // Shared map stores resolvers across `T` instantiations; erase the union.\n sub.resolvers.add({\n resolve: resolve as (data: unknown) => void,\n reject,\n });\n }),\n staleTime: Infinity,\n refetchOnWindowFocus: false,\n refetchOnMount: false,\n refetchOnReconnect: false,\n gcTime: 0,\n };\n}\n\nexport function modelenceMutation<T = unknown>(methodName: string, defaultArgs: Args = {}) {\n return {\n mutationFn: (variables: Args = {}) =>\n callMethod<T>(methodName, { ...defaultArgs, ...variables }),\n };\n}\n\nexport type ModelenceQueryKey<T extends string, U extends Args = Args> = readonly [T, U];\n\n/** Builds a query key matching `modelenceQuery(...)` for cache operations. */\nexport function createQueryKey<T extends string, U extends Args = Args>(\n methodName: T,\n args: U = {} as U\n): ModelenceQueryKey<T, U> {\n return [methodName, args] as const;\n}\n","'use client';\n\nimport { useState, type ReactNode } from 'react';\nimport {\n QueryClient,\n QueryClientProvider,\n HydrationBoundary,\n type DehydratedState,\n} from '@tanstack/react-query';\nimport { connectModelenceQueryClient } from './query';\n\nconst SSR_QUERY_STATE_SCRIPT_ID = '__MODELENCE_QUERY_STATE__';\n\nfunction readDehydratedState(): DehydratedState | undefined {\n if (typeof document === 'undefined') {\n return undefined;\n }\n\n const node = document.getElementById(SSR_QUERY_STATE_SCRIPT_ID);\n if (!node || !node.textContent) {\n return undefined;\n }\n\n try {\n return JSON.parse(node.textContent) as DehydratedState;\n } catch (e) {\n console.error('Modelence: failed to parse SSR query state', e);\n return undefined;\n }\n}\n\ninterface ModelenceQueryProviderProps {\n children: ReactNode;\n client?: QueryClient;\n dehydratedState?: DehydratedState;\n}\n\nexport function ModelenceQueryProvider({\n children,\n client,\n dehydratedState,\n}: ModelenceQueryProviderProps) {\n const [internalClient] = useState(() => {\n const qc =\n client ??\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 60 * 1000,\n },\n },\n });\n if (typeof window !== 'undefined') {\n connectModelenceQueryClient(qc);\n }\n return qc;\n });\n\n const state = dehydratedState ?? readDehydratedState();\n\n return (\n <QueryClientProvider client={internalClient}>\n <HydrationBoundary state={state}>{children}</HydrationBoundary>\n </QueryClientProvider>\n );\n}\n"]}
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { b as ClientInfo, c as ConfigKey, d as ConfigParams, A as AnyMethodShape, V as ValueType, e as ConfigType, O as OAuthProvider, W as WebsocketClientProvider, f as ClientChannel } from './types-B_R3eHmq.js';
1
+ import { b as ClientInfo, c as ConfigKey, d as ConfigParams, A as AnyMethodShape, V as ValueType, e as ConfigType, O as OAuthProvider, W as WebsocketClientProvider, f as ClientChannel } from './types-B8uEAj0y.js';
2
2
  import { ObjectId } from 'mongodb';
3
3
  import React, { ReactNode } from 'react';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
@@ -17,6 +17,16 @@ interface ClientConfig {
17
17
  * Defaults to `window.location.href` when not provided.
18
18
  */
19
19
  openUrl?: (url: string) => void;
20
+ /**
21
+ * Credentials mode for method-call requests. Defaults to `'include'`, which
22
+ * browser apps need for the cookie-based flows (password reset, magic link).
23
+ *
24
+ * Clients configured with token-in-body auth (React Native / Expo) never use
25
+ * cookies, so set `'omit'` there — on Expo Web a credentialed cross-origin
26
+ * request is otherwise blocked by any server answering
27
+ * `Access-Control-Allow-Origin: *`, surfacing as "TypeError: Failed to fetch".
28
+ */
29
+ credentials?: RequestCredentials;
20
30
  }
21
31
  /**
22
32
  * Configure the Modelence client for non-browser environments like React Native.
@@ -423,15 +433,149 @@ declare function logout(): Promise<void>;
423
433
  declare function sendResetPasswordToken(options: {
424
434
  email: string;
425
435
  }): Promise<void>;
436
+ /**
437
+ * Send a magic sign-in link to the given email address.
438
+ *
439
+ * Clicking the emailed link signs the user in. When the server enables
440
+ * `auth.magicLink.allowSignup`, this also works for new users — the account is
441
+ * created when the link is used; otherwise unknown emails receive no email.
442
+ * A generic response is always returned to avoid leaking account information.
443
+ *
444
+ * @example
445
+ * ```ts
446
+ * await sendMagicLink({ email: 'user@example.com' });
447
+ * ```
448
+ * @param options.email - The email address to send the magic link to.
449
+ */
450
+ declare function sendMagicLink(options: {
451
+ email: string;
452
+ }): Promise<void>;
453
+ /**
454
+ * Complete a magic link sign-in.
455
+ *
456
+ * Call this from the page the magic link landing route redirects to. The
457
+ * token is exchanged server-side via an httpOnly cookie, so no arguments are
458
+ * needed. Signs the user in — creating the account first when the email is
459
+ * not registered yet and the server enables `auth.magicLink.allowSignup` —
460
+ * and returns the logged-in user.
461
+ *
462
+ * @example
463
+ * ```ts
464
+ * const user = await loginWithMagicLink();
465
+ * ```
466
+ */
467
+ declare function loginWithMagicLink(): Promise<{
468
+ id: string;
469
+ handle: string;
470
+ roles: string[];
471
+ hasRole: (role: string) => boolean;
472
+ requireRole: (role: string) => void;
473
+ firstName?: string;
474
+ lastName?: string;
475
+ avatarUrl?: string;
476
+ } | null>;
477
+ /**
478
+ * Complete a magic link sign-in by typing the one-time code from the email.
479
+ *
480
+ * Alternative to `loginWithMagicLink()` for contexts where clicking the link
481
+ * can't reach the app — native apps without deep links, or when the email is
482
+ * read on a different device. Signs the user in — creating the account first
483
+ * when the email is not registered yet and the server enables
484
+ * `auth.magicLink.allowSignup` — and returns the logged-in user.
485
+ *
486
+ * @example
487
+ * ```ts
488
+ * const user = await loginWithOneTimeCode({ email: 'user@example.com', code: '482193' });
489
+ * ```
490
+ * @param options.email - The email the magic link was sent to.
491
+ * @param options.code - The one-time code from the email.
492
+ */
493
+ declare function loginWithOneTimeCode(options: {
494
+ email: string;
495
+ code: string;
496
+ }): Promise<{
497
+ id: string;
498
+ handle: string;
499
+ roles: string[];
500
+ hasRole: (role: string) => boolean;
501
+ requireRole: (role: string) => void;
502
+ firstName?: string;
503
+ lastName?: string;
504
+ avatarUrl?: string;
505
+ } | null>;
426
506
  /**
427
507
  * Reset password.
428
- * @param options.token - The password reset token.
508
+ *
509
+ * The token is normally exchanged server-side via an httpOnly cookie, so the
510
+ * client only submits the new password. Pass `token` only for legacy flows
511
+ * that still carry it client-side (deprecated).
512
+ *
513
+ * @param options.token - Reset token (optional; read from the httpOnly cookie when omitted).
429
514
  * @param options.password - The new password.
430
515
  */
431
516
  declare function resetPassword(options: {
432
- token: string;
517
+ token?: string;
433
518
  password: string;
434
519
  }): Promise<void>;
520
+ /**
521
+ * Start an OAuth sign-in.
522
+ *
523
+ * On the web this navigates to the provider and the flow finishes on its own —
524
+ * the session cookie is set and the browser lands back on your site.
525
+ *
526
+ * On React Native (any client configured with `openUrl`) pass `redirectUri`: the
527
+ * device browser opens the provider, and when the flow completes Modelence
528
+ * redirects back to that deep link with a single-use `code` query parameter.
529
+ * Hand that code to {@link loginWithOAuth} to finish signing in. The redirect
530
+ * target must be listed in the server's `auth.mobile.redirectUrls`, otherwise
531
+ * the request is rejected before the provider is ever reached.
532
+ *
533
+ * @example Web
534
+ * ```ts
535
+ * await signInWithOAuth({ provider: 'google' });
536
+ * ```
537
+ *
538
+ * @example React Native
539
+ * ```ts
540
+ * await signInWithOAuth({ provider: 'google', redirectUri: 'myapp://auth' });
541
+ *
542
+ * Linking.addEventListener('url', async ({ url }) => {
543
+ * const code = new URL(url).searchParams.get('code');
544
+ * if (code) await loginWithOAuth({ code });
545
+ * });
546
+ * ```
547
+ * @param options.provider - The OAuth provider to sign in with ('google' or 'github').
548
+ * @param options.redirectUri - Deep link to return to. Required on React Native.
549
+ */
550
+ declare function signInWithOAuth(options: {
551
+ provider: OAuthProvider;
552
+ redirectUri?: string;
553
+ }): Promise<void>;
554
+ /**
555
+ * Complete a native OAuth sign-in with the code from the deep link.
556
+ *
557
+ * Exchanges the single-use code that {@link signInWithOAuth} delivered to your
558
+ * app's deep link for a session, stores the auth token, and returns the
559
+ * signed-in user. Codes are valid for one minute and can only be redeemed once.
560
+ *
561
+ * @example
562
+ * ```ts
563
+ * const user = await loginWithOAuth({ code });
564
+ * ```
565
+ * @param options.code - The `code` query parameter from the deep link.
566
+ */
567
+ declare function loginWithOAuth(options: {
568
+ code: string;
569
+ }): Promise<{
570
+ id: string;
571
+ handle: string;
572
+ roles: string[];
573
+ hasRole: (role: string) => boolean;
574
+ requireRole: (role: string) => void;
575
+ firstName?: string;
576
+ lastName?: string;
577
+ avatarUrl?: string;
578
+ } | null>;
435
579
  /**
436
580
  * Link an OAuth provider to the currently signed-in user's account.
437
581
  * Redirects the browser to the OAuth provider's authorization page.
@@ -442,9 +586,13 @@ declare function resetPassword(options: {
442
586
  * linkOAuthProvider({ provider: 'google' });
443
587
  * ```
444
588
  * @param options.provider - The OAuth provider to link ('google' or 'github').
589
+ * @param options.redirectUri - Deep link to return to once linking completes.
590
+ * React Native only; must be listed in the server's `auth.mobile.redirectUrls`.
591
+ * Without it the flow ends in the device browser instead of back in the app.
445
592
  */
446
593
  declare function linkOAuthProvider(options: {
447
594
  provider: OAuthProvider;
595
+ redirectUri?: string;
448
596
  }): Promise<void>;
449
597
  /**
450
598
  * Unlink an OAuth provider from the currently signed-in user's account.
@@ -472,4 +620,4 @@ declare function getLocalStorageSession(): any;
472
620
 
473
621
  declare const AppProvider: any;
474
622
 
475
- export { AppProvider, type CallMethodOptions, ClientChannel, type ClientConfig, type MethodArgs, MethodError, ModelenceQueryClient, type ModelenceQueryKey, ModelenceQueryProvider, type UserInfo, ValueType, callMethod, configureClient, connectModelenceQueryClient, createClientModule, createQueryKey, disconnectModelenceQueryClient, getConfig, getLocalStorageSession, getWebsocketClientProvider, linkOAuthProvider, loginWithPassword, logout, modelenceLiveQuery, modelenceMutation, modelenceQuery, renderApp, resendEmailVerification, resetPassword, sendResetPasswordToken, setWebsocketClientProvider, signupWithPassword, startWebsockets, subscribeLiveQuery, systemConfig, unlinkOAuthProvider, updateProfile, useSession, verifyEmail };
623
+ export { AppProvider, type CallMethodOptions, ClientChannel, type ClientConfig, type MethodArgs, MethodError, ModelenceQueryClient, type ModelenceQueryKey, ModelenceQueryProvider, type UserInfo, ValueType, callMethod, configureClient, connectModelenceQueryClient, createClientModule, createQueryKey, disconnectModelenceQueryClient, getConfig, getLocalStorageSession, getWebsocketClientProvider, linkOAuthProvider, loginWithMagicLink, loginWithOAuth, loginWithOneTimeCode, loginWithPassword, logout, modelenceLiveQuery, modelenceMutation, modelenceQuery, renderApp, resendEmailVerification, resetPassword, sendMagicLink, sendResetPasswordToken, setWebsocketClientProvider, signInWithOAuth, signupWithPassword, startWebsockets, subscribeLiveQuery, systemConfig, unlinkOAuthProvider, updateProfile, useSession, verifyEmail };
package/dist/client.js CHANGED
@@ -1,2 +1,2 @@
1
- export{f as AppProvider,e as ClientChannel,a as createClientModule,d as renderApp,b as systemConfig}from'./chunk-TBGXZXAA.js';export{i as ModelenceQueryClient,n as ModelenceQueryProvider,f as connectModelenceQueryClient,m as createQueryKey,h as disconnectModelenceQueryClient,d as getWebsocketClientProvider,k as modelenceLiveQuery,l as modelenceMutation,j as modelenceQuery,c as setWebsocketClientProvider,e as startWebsockets,b as subscribeLiveQuery}from'./chunk-YRR32LTF.js';export{q as MethodError,t as callMethod,b as configureClient,v as getConfig,a as getLocalStorageSession,l as linkOAuthProvider,e as loginWithPassword,i as logout,h as resendEmailVerification,k as resetPassword,j as sendResetPasswordToken,d as signupWithPassword,m as unlinkOAuthProvider,f as updateProfile,E as useSession,g as verifyEmail}from'./chunk-YLLX26A4.js';import'./chunk-5M6FUMUK.js';import'./chunk-DO5TZLF5.js';//# sourceMappingURL=client.js.map
1
+ export{f as AppProvider,e as ClientChannel,a as createClientModule,d as renderApp,b as systemConfig}from'./chunk-YM6DVNYH.js';export{i as ModelenceQueryClient,n as ModelenceQueryProvider,f as connectModelenceQueryClient,m as createQueryKey,h as disconnectModelenceQueryClient,d as getWebsocketClientProvider,k as modelenceLiveQuery,l as modelenceMutation,j as modelenceQuery,c as setWebsocketClientProvider,e as startWebsockets,b as subscribeLiveQuery}from'./chunk-ZEXT732Q.js';export{v as MethodError,y as callMethod,b as configureClient,A as getConfig,a as getLocalStorageSession,q as linkOAuthProvider,l as loginWithMagicLink,p as loginWithOAuth,m as loginWithOneTimeCode,e as loginWithPassword,i as logout,h as resendEmailVerification,n as resetPassword,k as sendMagicLink,j as sendResetPasswordToken,o as signInWithOAuth,d as signupWithPassword,r as unlinkOAuthProvider,f as updateProfile,J as useSession,g as verifyEmail}from'./chunk-BJWGBMNX.js';import'./chunk-5M6FUMUK.js';import'./chunk-DO5TZLF5.js';//# sourceMappingURL=client.js.map
2
2
  //# sourceMappingURL=client.js.map
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { C as ConfigSchema, W as WebsocketClientProvider, a as WebsocketServerProvider } from './types-B_R3eHmq.js';
1
+ export { C as ConfigSchema, W as WebsocketClientProvider, a as WebsocketServerProvider } from './types-B8uEAj0y.js';
2
2
  export { M as ModelenceConfig } from './index-CgNFVSg6.js';
3
3
  import 'http';
4
4
  import 'mongodb';
@@ -26,7 +26,7 @@ declare class AuthError extends ModelenceError {
26
26
  }
27
27
  declare class ValidationError extends ModelenceError {
28
28
  status: number;
29
- constructor(message: string);
29
+ constructor(message: string, code?: string);
30
30
  }
31
31
  declare class RateLimitError extends ModelenceError {
32
32
  status: number;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export{b as AuthError,a as ModelenceError,d as RateLimitError,c as ValidationError}from'./chunk-MIRF7FP3.js';import'./chunk-55J6XMHW.js';export{a as time}from'./chunk-DO5TZLF5.js';//# sourceMappingURL=index.js.map
1
+ export{b as AuthError,a as ModelenceError,d as RateLimitError,c as ValidationError}from'./chunk-VYR7VQMQ.js';import'./chunk-55J6XMHW.js';export{a as time}from'./chunk-DO5TZLF5.js';//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
@@ -1,2 +1,2 @@
1
- export{l as author,i as bin,n as bugs,s as default,q as dependencies,d as description,p as devDependencies,g as exports,h as files,o as homepage,m as license,e as main,b as name,r as peerDependencies,k as repository,j as scripts,a as type,f as types,c as version}from'./chunk-KZZYA5HP.js';//# sourceMappingURL=package-BVTS5E5V.js.map
2
- //# sourceMappingURL=package-BVTS5E5V.js.map
1
+ export{l as author,i as bin,n as bugs,s as default,q as dependencies,d as description,p as devDependencies,g as exports,h as files,o as homepage,m as license,e as main,b as name,r as peerDependencies,k as repository,j as scripts,a as type,f as types,c as version}from'./chunk-5DFWJU3M.js';//# sourceMappingURL=package-Y67IHT4E.js.map
2
+ //# sourceMappingURL=package-Y67IHT4E.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"package-BVTS5E5V.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"package-Y67IHT4E.js"}
@@ -0,0 +1,2 @@
1
+ import {a,b,c}from'./chunk-MQQLQMPM.js';import'./chunk-6BB456MV.js';import'./chunk-VF4RU7MF.js';import {a as a$1,n}from'./chunk-ZEXT732Q.js';import {H,z,I}from'./chunk-BJWGBMNX.js';import'./chunk-5M6FUMUK.js';import'./chunk-DO5TZLF5.js';import {renderToPipeableStream}from'react-dom/server';import {Writable}from'stream';import {QueryClient,dehydrate}from'@tanstack/react-query';import {jsx}from'react/jsx-runtime';var J=()=>{let r=c();return r?I(r.session.user):null},M=r=>{let n=c();if(n)return n.session.configs[r]?.value};function D(){H(J),z(M);}async function X(r){let{callContext:n$1,loadingElement:C,routesElement:S,router:u,location:x,onShellReady:E,onError:b$1}=r;D();let l=await a("_system.session.init",{},n$1),i=new QueryClient({defaultOptions:{queries:{retry:false,gcTime:0}}}),O=u?u({children:S,location:x}):S,Q=jsx(a$1,{loadingElement:C,children:jsx(n,{client:i,children:O})}),a$2=null;await new Promise((s,m)=>{b({callContext:n$1,queryClient:i,session:{user:l.user,configs:l.configs??{}}},()=>{let e=renderToPipeableStream(Q,{onShellReady(){a$2=e,E?.(),s(e);},onShellError(t){m(t);},onError(t){b$1?.(t);}});return e});});let d=null,_=s=>new Promise((m,e)=>{if(!a$2){e(new Error("SSR stream was not initialized"));return}let t=new Writable({write(o,c,I){s.write(o,N=>I(N??void 0));},final(o){try{let c=dehydrate(i);d=JSON.stringify(c);}finally{i.clear();}o(),m();}});t.on("error",o=>{s.destroy(o),e(o);}),s.on("error",e),a$2.pipe(t);});return {sessionState:JSON.stringify({session:l}),pipe:_,getQueryState:()=>{if(d===null)throw new Error("getQueryState() called before stream finished");return d}}}export{X as renderSsrTreeStream};//# sourceMappingURL=render-G33LE5AY.js.map
2
+ //# sourceMappingURL=render-G33LE5AY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ssr/render.tsx"],"names":["sessionResolver","ctx","getSsrContext","_parseSessionUser","configResolver","key","ensureSsrResolversInstalled","_setSsrSessionResolver","_setSsrConfigResolver","renderSsrTreeStream","options","callContext","loadingElement","routesElement","router","location","onShellReady","onError","sessionPayload","callInProcessMethod","queryClient","QueryClient","routedTree","tree","jsx","AppProvider","ModelenceQueryProvider","streamRef","resolve","reject","runWithSsrContext","stream","renderToPipeableStream","error","queryStateJson","pipe","destination","passthrough","Writable","chunk","_encoding","callback","err","dehydratedState","dehydrate"],"mappings":"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","file":"render-G33LE5AY.js","sourcesContent":["import React from 'react';\nimport { renderToPipeableStream, type PipeableStream } from 'react-dom/server';\nimport { Writable } from 'node:stream';\nimport { QueryClient, dehydrate, type DehydratedState } from '@tanstack/react-query';\nimport { AppProvider } from '../client/AppProvider';\nimport { ModelenceQueryProvider } from '../client/queryProvider';\nimport { getSsrContext, runWithSsrContext } from './context';\nimport { callInProcessMethod } from './callInProcess';\nimport type { Context } from '../methods/types';\nimport {\n _parseSessionUser,\n _setSsrSessionResolver,\n type SessionInitPayload,\n} from '../client/session';\nimport { _setSsrConfigResolver } from '../config/client';\nimport type { ConfigKey, Configs } from '../config/types';\nimport type { SsrRouter } from '../client/renderApp';\n\nconst sessionResolver = () => {\n const ctx = getSsrContext();\n if (!ctx) {\n return null;\n }\n return _parseSessionUser(ctx.session.user);\n};\n\nconst configResolver = (key: ConfigKey) => {\n const ctx = getSsrContext();\n if (!ctx) {\n return undefined;\n }\n return ctx.session.configs[key]?.value;\n};\n\nfunction ensureSsrResolversInstalled() {\n _setSsrSessionResolver(sessionResolver);\n _setSsrConfigResolver(configResolver);\n}\n\nexport type SsrRenderOptions = {\n callContext: Context;\n loadingElement: React.ReactNode;\n routesElement: React.ReactNode;\n router?: SsrRouter;\n location?: string;\n};\n\nexport type SsrStreamHandle = {\n /** Session bootstrap payload — inline before the shell flushes. */\n sessionState: string;\n /** Pipe React's HTML into `destination`. Resolves when streaming finishes. */\n pipe: (destination: Writable) => Promise<void>;\n /** Dehydrated query state. Only call after `pipe()` resolves. */\n getQueryState: () => string;\n};\n\nexport type SsrStreamOptions = SsrRenderOptions & {\n /** Fires when the shell is flushed; caller writes prelude + state here. */\n onShellReady?: () => void;\n /** Non-fatal SSR errors (Suspense fallbacks, etc.). */\n onError?: (error: unknown) => void;\n};\n\nexport async function renderSsrTreeStream(options: SsrStreamOptions): Promise<SsrStreamHandle> {\n const { callContext, loadingElement, routesElement, router, location, onShellReady, onError } =\n options;\n\n ensureSsrResolversInstalled();\n\n const sessionPayload = await callInProcessMethod<SessionInitPayload>(\n '_system.session.init',\n {},\n callContext\n );\n\n const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: false,\n gcTime: 0,\n },\n },\n });\n\n const routedTree = router ? router({ children: routesElement, location }) : routesElement;\n const tree = (\n <AppProvider loadingElement={loadingElement}>\n <ModelenceQueryProvider client={queryClient}>{routedTree}</ModelenceQueryProvider>\n </AppProvider>\n );\n\n let streamRef: PipeableStream | null = null;\n // Resolves with the stream once React renders above-fallback content;\n // rejects on shell errors so the caller can fall back to a static response.\n const shellReady = new Promise<PipeableStream>((resolve, reject) => {\n // Run the render inside the SSR context so components can resolve\n // session/config/query state from the per-request scope.\n runWithSsrContext(\n {\n callContext,\n queryClient,\n session: {\n user: sessionPayload.user,\n configs: (sessionPayload.configs as Configs) ?? {},\n },\n },\n () => {\n const stream = renderToPipeableStream(tree, {\n onShellReady() {\n streamRef = stream;\n onShellReady?.();\n resolve(stream);\n },\n onShellError(error) {\n reject(error);\n },\n onError(error) {\n onError?.(error);\n },\n });\n return stream;\n }\n );\n });\n\n // Await so shell errors surface before the caller starts piping.\n await shellReady;\n\n let queryStateJson: string | null = null;\n\n const pipe = (destination: Writable): Promise<void> => {\n return new Promise((resolve, reject) => {\n if (!streamRef) {\n reject(new Error('SSR stream was not initialized'));\n return;\n }\n\n // react-dom calls `destination.end()` when done. The caller still needs\n // to write the epilogue + query state, so wrap with a passthrough whose\n // `final()` resolves the pipe promise without closing the response.\n const passthrough = new Writable({\n write(chunk, _encoding, callback) {\n destination.write(chunk, (err) => callback(err ?? undefined));\n },\n final(callback) {\n try {\n const dehydratedState: DehydratedState = dehydrate(queryClient);\n queryStateJson = JSON.stringify(dehydratedState);\n } finally {\n queryClient.clear();\n }\n callback();\n resolve();\n },\n });\n\n passthrough.on('error', (err) => {\n destination.destroy(err);\n reject(err);\n });\n destination.on('error', reject);\n\n streamRef.pipe(passthrough);\n });\n };\n\n return {\n sessionState: JSON.stringify({ session: sessionPayload }),\n pipe,\n getQueryState: () => {\n if (queryStateJson === null) {\n throw new Error('getQueryState() called before stream finished');\n }\n return queryStateJson;\n },\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export{c as _getSsrSnapshot,d as renderApp}from'./chunk-YM6DVNYH.js';import'./chunk-ZEXT732Q.js';import'./chunk-BJWGBMNX.js';import'./chunk-5M6FUMUK.js';import'./chunk-DO5TZLF5.js';//# sourceMappingURL=renderApp-F7NZT5JC.js.map
2
+ //# sourceMappingURL=renderApp-F7NZT5JC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"renderApp-QYMNQ3KS.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"renderApp-F7NZT5JC.js"}
@@ -0,0 +1,2 @@
1
+ export{g as getCallContext,f as startServer}from'./chunk-KYQ6UVLY.js';import'./chunk-5DFWJU3M.js';import'./chunk-6BB456MV.js';import'./chunk-VYR7VQMQ.js';import'./chunk-VF4RU7MF.js';import'./chunk-5M6FUMUK.js';import'./chunk-DO5TZLF5.js';//# sourceMappingURL=server-BEYRNZY5.js.map
2
+ //# sourceMappingURL=server-BEYRNZY5.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"server-KAHRRRDU.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"server-BEYRNZY5.js"}