@blocklet/pages-kit-inner-components 0.6.10 → 0.6.12

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.
@@ -0,0 +1 @@
1
+ "use strict";const d=require("./components-CacZMc0_.js"),F=require("@syncedstore/core"),Je=require("yjs"),Ke=require("@blocklet/pages-kit/utils/data-source"),Q=require("@blocklet/pages-kit/utils/route"),He=require("lodash"),We=require("@blocklet/sdk/lib/config"),I=require("fs"),g=require("path"),Te=require("@blocklet/pages-kit/utils/common"),Qe=require("@blocklet/pages-kit/utils/page-model"),Xe=require("@blocklet/pages-kit/utils/property"),Ie=require("@blocklet/sdk/lib/component"),Ze=require("@reactivedata/reactive"),X=require("glob"),et=require("lib0/decoding"),tt=require("lib0/encoding"),st=require("lodash/cloneDeep"),at=require("lodash/debounce"),nt=require("lodash/get"),ot=require("lodash/isEmpty"),rt=require("lodash/set"),it=require("lodash/union"),be=require("lru-cache"),ct=require("p-limit"),C=require("sequelize"),lt=require("stream/promises"),pt=require("tar"),Y=require("ufo"),ut=require("wait-on"),z=require("y-protocols/awareness"),le=require("y-protocols/sync"),dt=require("yaml");require("sqlite3");require("@blocklet/pages-kit/types/state");const M=t=>t&&t.__esModule?t:{default:t};function ae(t){if(t&&t.__esModule)return t;const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const s in t)if(s!=="default"){const a=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,a.get?a:{enumerable:!0,get:()=>t[s]})}}return e.default=t,Object.freeze(e)}const $=ae(Je),E=M(We),pe=ae(et),v=ae(tt),ft=M(st),Re=M(at),Ee=M(nt),we=M(ot),De=M(rt),gt=M(it),mt=M(ct),ht=M(ut),x=ae(dt),yt=C.DataTypes.sqlite.DATE.parse;C.DataTypes.sqlite.DATE.parse=(t,e)=>typeof t=="number"?new Date(t):yt(t,e);const U=new C.Sequelize({dialect:"sqlite",storage:d.databaseUrl,benchmark:process.env.ENABLE_SEQUELIZE_BENCHMARK==="true",retry:{match:[/SQLITE_BUSY/],name:"query",max:10},logging:process.env.ENABLE_SEQUELIZE_LOGGING==="true"?console.log:!1});U.query("pragma journal_mode = WAL;");U.query("pragma synchronous = normal;");U.query("pragma journal_size_limit = 33554432;");U.query("pragma cache_size = -2000;");U.query("pragma mmap_size = 33554432;");process.on("SIGINT",async()=>{await U.close(),process.exit(0)});process.on("SIGTERM",async()=>{await U.close(),process.exit(0)});async function St(t,e){try{if(t.getDialect()!=="sqlite")return;const[s]=await t.query("SELECT 1");if(!s||s.length===0)return;await t.query("PRAGMA shrink_memory;")}catch(s){if(s.name==="SequelizeConnectionError"||s?.message&&/closed!/.test(s.message))return;console.error("Failed to cleanup SQLite memory",e,s)}}let fe=null;fe&&clearInterval(fe);fe=setInterval(async()=>{d.logger.info("Start cleanupSqliteMemory"),await St(U,d.databaseUrl),d.logger.info("End cleanupSqliteMemory")},60*1e3*10);class Ae extends C.Model{}Ae.init({id:{type:C.DataTypes.UUID,allowNull:!1,primaryKey:!0,defaultValue:C.DataTypes.UUIDV4},projectId:{type:C.DataTypes.UUID,allowNull:!1},componentId:{type:C.DataTypes.STRING,allowNull:!1}},{sequelize:U,tableName:"ProjectComponents",timestamps:!1});class L extends C.Model{static async getProjectByIdOrSlug(e){return L.findOne({where:{[C.Op.or]:[{id:e},{slug:e}]}})}}L.init({id:{type:C.DataTypes.UUID,defaultValue:C.DataTypes.UUIDV4,primaryKey:!0},name:{type:C.DataTypes.STRING,allowNull:!1},description:C.DataTypes.TEXT,createdAt:C.DataTypes.DATE,updatedAt:C.DataTypes.DATE,createdBy:{type:C.DataTypes.STRING,allowNull:!1},updatedBy:{type:C.DataTypes.STRING,allowNull:!1},slug:C.DataTypes.STRING,icon:C.DataTypes.STRING,pinnedAt:C.DataTypes.DATE,useAllResources:C.DataTypes.BOOLEAN,npmSecret:C.DataTypes.STRING,relatedBlocklets:{type:C.DataTypes.JSON,allowNull:!1,defaultValue:{},get(){const t=this.getDataValue("relatedBlocklets");if(typeof t=="object")return t??{};try{return t?JSON.parse(t):{}}catch(e){return d.logger.error("Failed to parse relatedBlocklets",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("relatedBlocklets",t?JSON.stringify(t):"{}")}catch(e){d.logger.error("Failed to set relatedBlocklets",{error:e,value:t}),this.setDataValue("relatedBlocklets","{}")}}},productionState:{type:C.DataTypes.JSON,allowNull:!1,defaultValue:{},get(){const t=this.getDataValue("productionState");if(typeof t=="object")return t??{};try{return t?JSON.parse(t):{}}catch(e){return d.logger.error("Failed to parse productionState",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("productionState",t?JSON.stringify(t):"{}")}catch(e){d.logger.error("Failed to set productionState",{error:e,value:t}),this.setDataValue("productionState","{}")}}}},{sequelize:U,paranoid:!0});L.hasMany(Ae,{foreignKey:"projectId",as:"components"});const It="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o",ge="page",me="trigger-reload-project-resource",Pe=It,bt="z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM";function Z(t){t.observeDeep(e=>{e.some(s=>s.changes.keys.has("updatedAt")||s.changes.keys.has("publishedAt"))||t.set("updatedAt",new Date().toISOString())})}function Le(){return I.mkdtempSync(g.join(E.default.env.dataDir,"tmp-"))}function ee(t,e,s=[]){return Array.isArray(t)?t.flatMap((a,n)=>ee(a,e,[...s,n])):typeof t=="object"?t===null?[]:Object.entries(t).flatMap(([a,n])=>ee(n,e,[...s,a])):e(t)?[s]:[]}function R(t){return t.filter(e=>e!=null)}function Et(t){t.pages&&Object.keys(t.pages).forEach(s=>{const a=F.getYjsValue(t.pages[s]);a&&a instanceof $.Map&&Z(a)});const e=F.getYjsValue(t.pages);e&&e instanceof $.Map&&e.observe(s=>{s.changes.keys.forEach((a,n)=>{if(a.action==="add"){const o=F.getYjsValue(t.pages[n]);o&&o instanceof $.Map&&Z(o)}})})}function wt(t){t.routes&&Object.keys(t.routes).forEach(s=>{const a=F.getYjsValue(t.routes?.[s]);a&&a instanceof $.Map&&Z(a)});const e=F.getYjsValue(t.routes);e&&e instanceof $.Map&&e.observe(s=>{s.changes.keys.forEach((a,n)=>{if(a.action==="add"){const o=F.getYjsValue(t.routes?.[n]);o&&o instanceof $.Map&&Z(o)}})})}function At(t,e){for(const s of e||Object.keys(t.routes||{})){let a=s,n=[];if(s.includes("-")){const[o,...i]=s.split("-");a=o,n=i||[]}if(t.routes?.[a]!==void 0){t.routes[a].publishedAt=new Date().toISOString();const o=t.routes[a];if(!o||!o.params||o.params.length===0)continue;if(s.includes("-")&&n.length>0){const i=Q.getRouteMetaDataByOptionIds(n,o);i&&(i.publishedAt=new Date().toISOString())}if(!e){const i=Q.generateParamCombinations({basePath:o.path,params:o.params,routeId:o.id,paramsOptions:o.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const c of i)c.routeMetaData??={},c.routeMetaData.publishedAt=new Date().toISOString()}}}}function ue({page:t,route:e,state:s,routeId:a,routePathInfo:n}){d.logger.info(`Executing datasource data assembly, routeId: ${a}, routePathInfo: ${JSON.stringify(n)}`);const o={...He.cloneDeep(t),id:a,slug:n?.path??e.path,createdAt:e.createdAt,updatedAt:n?.routeMetaData?.updatedAt??e.updatedAt,publishedAt:n?.routeMetaData?.publishedAt??e.publishedAt,isPublic:(n?.routeMetaData?.isPublic??e.isPublic)&&e.isPublic};for(const i of s.supportedLocales){if(e.dataSource){let c=e.id;n&&(c=n.paramOptionIds.join("-"));const p=e.dataSource.pathDataMappings?.[c]?.dataCache?.[i.locale]??e.dataSource.pathDataMappings?.[c]?.dataCache?.[s.config.defaultLocale||"en"];if(!p)continue;Ke.setPageDataSource(o,s,i.locale,p)}n&&n.routeMetaData&&(n.routeMetaData.publishedAt=new Date().toISOString())}return o}const Pt=30*60*1e3,B=new be.LRUCache({max:100,ttl:Pt});function Ot(t,e=[]){let s=0;const a=Array.from(B.keys()),n=[];for(const o of t){n.push(`page-html:prod:${o}:lang-path=none`);for(const i of e)n.push(`page-html:prod:/${i}${o}:lang-path=${i}`)}for(const o of a){const i=o.split(":lang-path=")[0]||"";for(const c of n){const m=(c.split(":lang-path=")[0]||"").replace(/\/:[^/]+/g,"");if(i.startsWith(m)){B.delete(o),s++,d.logger.info(`[Cache CLEAR] key: ${o}`);break}}}return d.logger.info(`[Cache CLEAR] cleared ${s} entries for patterns:`,n),s}function Ct({projectId:t,projectSlug:e,supportedLocales:s=[]}){let a=0;const n=Array.from(B.keys()),o=[];o.push(`page-html:prod:/${t}`),e&&e!==t&&o.push(`page-html:prod:/${e}`);for(const i of s)o.push(`page-html:prod:/${i}/${t}`),e&&e!==t&&(e!=="/"?o.push(`page-html:prod:/${i}/${e}`):o.push(`page-html:prod:/${i}`));for(const i of n)for(const c of o)if(i.startsWith(c)){B.delete(i),a++,d.logger.info(`[Cache CLEAR PROJECT] key: ${i}`);break}return d.logger.info(`[Cache CLEAR PROJECT] cleared ${a} entries for project ${t}${e?` (slug: ${e})`:""}`),a}function jt(){const t=B.size;return B.clear(),d.logger.info(`[Cache CLEAR ALL] cleared ${t} entries`),t}E.default.events.on(E.default.Events.envUpdate,jt);const{uploadToMediaKit:Tt}=require("@blocklet/uploader-server"),Oe=/^\w+(\w|-|\.)+\w+\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm)$/,J=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/i,ke=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/gi,Dt=1e4,kt=3e4,H=0,de=1,vt=0,Rt=1,he=E.default,q=g.join(process.env.BLOCKLET_DATA_DIR,"site-state"),Lt=["production","draft"],_t=["production"];function te(t){return t?.replace(/\//g,"|")||""}function _e(){const t=he.env.languages?.map(s=>({locale:s.code,name:s.name}))||[],e=t[0]?.locale||"en";return{pageIds:[],pages:{},routeIds:[],routes:{},dataSourceIds:[],dataSources:{},components:{},supportedLocales:t,config:{defaultLocale:e},resources:{}}}class O extends $.Doc{constructor(e){super(),this.options=e,I.existsSync(this.draftYjsFilePath)&&$.applyUpdate(this,I.readFileSync(this.draftYjsFilePath)),this.syncedStore=Ze.reactive(F.syncedStore({pages:{},pageIds:[],components:{},supportedLocales:[],config:{},resources:{},routeIds:[],routes:{},dataSourceIds:[],dataSources:{}},this)),this.initObserver(),this.on("update",this.updateHandler),this.awareness=new z.Awareness(this),this.awareness.on("update",this.awarenessChangeHandler),this.ensureDataStructure()}static RELEASE_DELAY=5*60*1e3;static PERIODIC_CHECK_INTERVAL=2*60*60*1e3;static sharedInstances={};static pageUrlMapCache=new be.LRUCache({max:100,ttl:1e3*60*60*24});static periodicCheckTimer;static safeDeleteProjectStateDir(e){if(!e)throw new Error("Should provide project context");try{const s=g.join(q,e),a=g.join(q,`@del-${e}`);I.renameSync(s,a)}catch(s){d.logger.error("Failed to safe delete project state dir:",s)}}static async getProjectIds(){return(await L.findAll({attributes:["id"],raw:!0}))?.map(e=>e.id)}static get projectIds(){return X.globSync("*/",{cwd:q,ignore:["@del-*","@tmp-*",".*","staging","production","@backup-*","undefined"]})}static get allShared(){return this.projectIds.map(e=>O.shared(e))}static shared(e){if(!e)throw new Error("Should provide project context");let s=O.sharedInstances[e];return s||(s=new O({path:g.join(q,e)}),O.sharedInstances[e]=s,s)}static async getProductionState(e){const s=await L.findByPk(e,{attributes:["productionState"]});if(we.default(s?.productionState)){const a=g.join(q,e,"production"),n=await Ce(a,{includeResources:!0})??_e();if(!n?.config?.defaultLocale){n.config??={};const o=he.env.languages?.map(i=>({locale:i.code,name:i.name}))||[];n.config.defaultLocale=o[0]?.locale}return n}return s?.productionState}destroy(){this.cancelRelease(),this.save({flush:!0}),this.conns.forEach((s,a)=>this.closeConn(a)),this.awareness.destroy();const e=g.basename(this.options.path);delete O.sharedInstances[e],super.destroy()}initObserver(){Et(this.syncedStore),wt(this.syncedStore)}get draftYjsFilePath(){return g.join(this.options.path,"draft.yjs")}static async getStateByProjectId(e,s){if(s==="draft"){const a=O.shared(e);return JSON.parse(JSON.stringify(a.syncedStore))}return O.getProductionState(e)}async getState(e){if(e==="draft")return JSON.parse(JSON.stringify(this.syncedStore));const s=g.basename(this.options.path);return O.getProductionState(s)}async setState(e,s){const a=await Ne(s,{exportAssets:!1,includeResources:!0}),n=this.getPublishDir(e);if(I.mkdirSync(g.dirname(n),{recursive:!0}),I.rmSync(n,{force:!0,recursive:!0}),I.renameSync(a,n),e==="production"){const o=g.basename(this.options.path);O.pageUrlMapCache.delete(o),await L.update({productionState:{...s}},{where:{id:o}})}}getPublishDir(e){return g.join(this.options.path,e)}syncedStore;conns=new Map;awareness;releaseTimer;awarenessChangeHandler=({added:e,updated:s,removed:a},n)=>{const o=e.concat(s,a);if(n!==null){const p=this.conns.get(n);p&&(e.forEach(m=>{p.add(m)}),a.forEach(m=>{p.delete(m)}))}const i=v.createEncoder();v.writeVarUint(i,de),v.writeVarUint8Array(i,z.encodeAwarenessUpdate(this.awareness,o));const c=v.toUint8Array(i);this.conns.forEach((p,m)=>this.send(m,c))};updateHandler=e=>{const s=v.createEncoder();v.writeVarUint(s,H),le.writeUpdate(s,e);const a=v.toUint8Array(s);this.conns.forEach((n,o)=>this.send(o,a))};ensureDataStructure=()=>{const{supportedLocales:e,pages:s,pageIds:a,config:n,routes:o,routeIds:i}=this.syncedStore;{const c=new Set(Object.keys(s));let p=0;for(;p<a.length;){const m=a[p];c.has(m)?(c.delete(m),p++):a.splice(p,1)}}{const c=new Set(Object.keys(o));let p=0;for(;p<i.length;){const m=i[p];c.has(m)?(c.delete(m),p++):i.splice(p,1)}}e.splice(0,e.length),e.push(...he.env.languages.map(c=>({locale:c.code,name:c.name}))),n.defaultLocale=e[0]?.locale;{let c=0;const p=new Set;for(;c<e.length;){const{locale:m}=e[c];p.has(m)?e.splice(c,1):(c++,p.add(m))}}};send=(e,s)=>{e.readyState!==vt&&e.readyState!==Rt&&this.closeConn(e);try{e.send(s,a=>{a&&this.closeConn(e)})}catch{this.closeConn(e)}};closeConn=e=>{if(e.removeAllListeners(),this.conns.has(e)){const s=this.conns.get(e);this.conns.delete(e),s&&z.removeAwarenessStates(this.awareness,Array.from(s),null)}e.close(),this.checkAndScheduleRelease()};checkAndScheduleRelease(){this.conns.size===0&&this.scheduleRelease()}scheduleRelease(){this.cancelRelease();const e=g.basename(this.options.path);this.releaseTimer=setTimeout(()=>{d.logger.info(`[SiteState] releasing instance due to no active connections: ${e}`),this.conns.size===0&&(this.releaseTimer=void 0,this.destroy())},O.RELEASE_DELAY),d.logger.info(`[SiteState] scheduled release for project ${e} in ${O.RELEASE_DELAY/1e3}s`)}cancelRelease(){if(this.releaseTimer){clearTimeout(this.releaseTimer),this.releaseTimer=void 0;const e=g.basename(this.options.path);d.logger.info(`[SiteState] cancelled scheduled release for project ${e}`)}}autoSave=Re.default(()=>{I.mkdirSync(g.dirname(this.draftYjsFilePath),{recursive:!0}),I.writeFileSync(this.draftYjsFilePath,$.encodeStateAsUpdate(this))},Dt);save=({flush:e=!1}={})=>{this.autoSave(),e&&this.autoSave.flush()};publish=async({mode:e,routes:s})=>{const a=await this.getState("draft"),n=await this.getState("production");await Se(a,n,{routes:s,mergeMode:"replace",deleteRoutes:!0,publishMode:e}),n.config.publishedAt=new Date().getTime(),At(this.syncedStore,s),await this.setState(e,n),await this.clearPageCacheForRoutes(s,n)};mergeState=async(e,s)=>{const a=JSON.parse(JSON.stringify(s));e.config.fontFamily??={};const n=a.config?.fontFamily,o=e.config?.fontFamily;e.config.fontFamily.title=n?.title||o?.title,e.config.fontFamily.description=n?.description||o?.description,await new Promise((i,c)=>{this.transact(async()=>{try{const p=await Se(e,s);i(p)}catch(p){c(p)}})})};clearPageCacheForRoutes=async(e,s)=>{const a=g.basename(this.options.path),o=(await L.findByPk(a))?.slug||a;if(d.logger.info(`[SiteState] clearing page cache for project ${a}, routes:`,e||[]),!e||e.length===0){Ct({projectId:a,projectSlug:o,supportedLocales:s.supportedLocales.map(m=>m.locale)});return}const i=s.supportedLocales.map(m=>m.locale),c=[],p=e.filter(m=>s.pages[m]);for(const m of p){const T=s.pages[m].slug;o&&o!==a&&(o==="/"?c.push(T):c.push(`/${o}${T}`)),c.push(`/${a}${T}`)}if(d.logger.info(`[SiteState] clearing page cache for project ${a}, pathPatterns:`,c),c.length>0){const m=Ot(c,i);d.logger.info(`[SiteState] cleared ${m} page cache entries for project ${a}, routes:`,e)}};addConnection=e=>{if(this.conns.has(e))return;this.cancelRelease(),e.binaryType="arraybuffer",this.conns.set(e,new Set),e.on("message",n=>this.messageListener(e,new Uint8Array(n)));let s=!0;const a=setInterval(()=>{if(!s)this.conns.has(e)&&this.closeConn(e),clearInterval(a);else if(this.conns.has(e)){s=!1;try{e.ping()}catch{this.closeConn(e),clearInterval(a)}}},kt);e.on("close",()=>{this.closeConn(e),clearInterval(a)}),e.on("pong",()=>{s=!0});{const n=v.createEncoder();v.writeVarUint(n,H),le.writeSyncStep1(n,this),this.send(e,v.toUint8Array(n));const o=this.awareness.getStates();if(o.size>0){const i=v.createEncoder();v.writeVarUint(i,de),v.writeVarUint8Array(i,z.encodeAwarenessUpdate(this.awareness,Array.from(o.keys()))),this.send(e,v.toUint8Array(i))}}};messageListener=(e,s)=>{try{const a=v.createEncoder(),n=pe.createDecoder(s),o=pe.readVarUint(n);switch(o){case H:v.writeVarUint(a,H),le.readSyncMessage(n,a,this,null),v.length(a)>1&&(this.ensureDataStructure(),this.send(e,v.toUint8Array(a)));break;case de:{z.applyAwarenessUpdate(this.awareness,pe.readVarUint8Array(n),e);break}default:d.logger.warn(`Unsupported messageType ${o}`)}}catch(a){d.logger.error(a)}this.save()};static async pageUrlMap(e,s){let a=[];s?a=[s]:a=await this.getProjectIds();let n={};if(e==="production"&&a?.length){const o=new Map(a?.map(i=>[i,!0])||[]);for(const i of a){const c=O.pageUrlMapCache.get(i);c&&(n={...n,...c},o.delete(i))}a=Array.from(o.keys())}if(a?.length){const o=await L.findAll({where:{id:{[C.Op.in]:a}}});await Promise.all(o?.map(async i=>{const c=i.id,p=i.slug||c,m={},k=e==="production"&&i?.productionState?i.productionState:await O.getStateByProjectId(i.id,e),T=gt.default(E.default.env.languages?.map(u=>u.code)||[],k.supportedLocales?.map(u=>u.locale)||[]),w=(u,l)=>{p&&(m[Y.joinURL("/",p,u)]={...l,shouldRedirect:!0,mainPage:!0}),m[Y.joinURL("/",c,u)]={...l,shouldRedirect:!0,mainPage:!0};for(const y of T){const j={...l,locale:y};m[Y.joinURL("/",y,c,u)]=j,p&&(m[Y.joinURL("/",y,p,u)]=j)}};if(e==="draft")for(const u of k.routeIds||[]){const l=k?.routes?.[u];if(!l)continue;if(l.params&&l.params.length>0){const h=Q.generateParamCombinations({basePath:l.path,params:l.params,routeId:l.id,paramsOptions:l.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const f of h){const S=f.path,A={projectId:c,projectSlug:p,pageSlug:S,pageId:l.displayTemplateId||"",routeId:u,defaultLocale:T?.[0],locales:T,publishedAt:k.config.publishedAt,isPublic:l.isPublic&&f?.routeMetaData?.isPublic};w(S,A)}}const y=l.path,j={projectId:c,projectSlug:p,pageSlug:y,pageId:l.displayTemplateId||"",routeId:u,defaultLocale:T?.[0],locales:T,publishedAt:k.config.publishedAt,isPublic:l.isPublic};w(y,j)}for(const u of k.pageIds){const l=k.pages[u];if(!l||e==="production"&&!l.isPublic)continue;const y=l.slug,j=i.slug||c,h={projectId:c,projectSlug:j,pageSlug:y,pageId:u,defaultLocale:T?.[0],locales:T,publishedAt:k.config.publishedAt,isPublic:l.isPublic,templateConfig:l.templateConfig};w(y,h)}e==="production"&&O.pageUrlMapCache.set(c,m),n={...n,...m}}))}return n}getDocumentSize(){return $.encodeStateAsUpdate(this).byteLength}static getInstancesSizeInfo(){const e=[];for(const[s,a]of Object.entries(O.sharedInstances)){const n=a.getDocumentSize();e.push({projectId:s,sizeInBytes:n,sizeInMB:`${(n/(1024*1024)).toFixed(2)} MB`,activeConnections:a.conns.size})}return e}static startPeriodicCheck(){this.periodicCheckTimer||(this.periodicCheckTimer=setInterval(()=>{this.performPeriodicCheck()},this.PERIODIC_CHECK_INTERVAL),d.logger.info(`[SiteState] periodic check started, interval: ${this.PERIODIC_CHECK_INTERVAL/(60*60*1e3)} hours`))}static stopPeriodicCheck(){this.periodicCheckTimer&&(clearInterval(this.periodicCheckTimer),this.periodicCheckTimer=void 0,d.logger.info("[SiteState] periodic check stopped"))}static performPeriodicCheck(){const e=Object.keys(O.sharedInstances).length,s=[],a=[];for(const[n,o]of Object.entries(O.sharedInstances))o.conns.size===0?s.push({projectId:n,instance:o}):a.push({projectId:n,connections:o.conns.size});if(d.logger.info(`[SiteState] periodic check summary: total instances: ${e}, with connections: ${a.length}, without connections: ${s.length}`),s.length>0){d.logger.info(`[SiteState] releasing ${s.length} instances without connections:`,s.map(o=>o.projectId));let n=0;for(const{projectId:o,instance:i}of s)try{d.logger.info(`[SiteState] releasing instance due to periodic check: ${o}`),i.destroy(),n++}catch(c){d.logger.error(`[SiteState] failed to release instance ${o} during periodic check:`,c)}d.logger.info(`[SiteState] periodic check completed: ${n}/${s.length} instances released successfully`)}else e>0?d.logger.debug("[SiteState] periodic check: all instances have active connections"):d.logger.debug("[SiteState] periodic check: no instances exist")}}async function $t(t,e,s){if(!t||!I.existsSync(t)||!I.lstatSync(t).isFile())return null;let a=s[t];return a||(a=(async()=>{try{return(await Tt({filePath:t,fileName:e}))?.data?.filename}catch(n){return d.logger.error(`Failed to upload asset ${t}:`,n),null}})(),s[t]=a),a}const $e=async(t,e)=>{const s=g.basename(t),a=await Ie.call({name:Pe,path:Y.joinURL("/uploads",s),responseType:"stream",method:"GET"});if(a.status>=200&&a.status<400){const n=I.createWriteStream(e);await lt.pipeline(a.data,n)}else throw new Error(`download asset failed ${a.status}`)},Ue=async(t,e)=>{await Promise.all(t.map(async s=>{try{await $e(s,g.join(e,g.basename(s)))}catch(a){d.logger.error(`Failed to export assets: ${s}, ${a}`)}}))};function Me(t){return Oe.test(t)?[t]:J.test(t)?(ke.lastIndex=0,Array.from(t.matchAll(ke)).map(s=>s[1]).filter(s=>!!s)):[]}async function W(t,e,s){const{getFilename:a,exportAssets:n}=s,o=g.join(e,a(t));if(I.mkdirSync(g.dirname(o),{recursive:!0}),I.writeFileSync(o,x.stringify(t)),n){const c=ee(t,p=>typeof p=="string"&&(Oe.test(p)||J.test(p))).map(p=>{const m=Ee.default(t,p);return Me(m)}).flat().filter(Boolean);await Ue(c,g.dirname(o))}}const ye=new be.LRUCache({max:100,ttl:1*60*1e3});async function ve(t,e,s){const a=ee(t,c=>typeof c=="string"&&(Oe.test(c)||J.test(c))),n=mt.default(2),o=a.map(c=>n(async()=>{try{const p=Ee.default(t,c),m=Me(p);for(const k of m){const T=g.basename(k),w=s.getFilePath(k,c),u=w?`${w}:${T}`:T,l=ye.get(u);if(l){J.test(p)||De.default(t,c,l);return}const y=await $t(w,T,e);y&&(J.test(p)||De.default(t,c,y),ye.set(u,y))}}catch(p){d.logger.error(`Failed to process upload for path ${c.join(".")}:`,p.message||p.reason)}})),i=await Promise.allSettled(o);s.onFinish?.(i)}async function Ne(t,{exportAssets:e,pageIds:s="all",componentIds:a="all",rawConfig:n,includeResources:o=!1,routeIds:i="all"}={}){const c=s==="all"?t.pageIds:s,p=Xe.getComponentDependencies({state:t,pageIds:c,componentIds:a==="all"?Object.keys(t.components):a}),m=i==="all"?t.routeIds:i,k=r=>({id:r.id,name:r.name,isTemplateSection:r.isTemplateSection??!1,templateDescription:r.templateDescription,llmConfig:r.llmConfig,component:r.component,config:r.config,visibility:r.visibility,sections:r?.sectionIds?R(r?.sectionIds?.map(b=>{const D=r.sections?.[b];return D&&k(D)})):void 0}),T=(r,b)=>({id:r.id,createdAt:r.createdAt,updatedAt:r.updatedAt,publishedAt:r.publishedAt,isPublic:r.isPublic??!0,templateConfig:r.templateConfig,meta:r.locales?.[b]??{},sections:R(r.sectionIds.map(D=>{const N=r.sections[D];return N&&k(N)})),dataSource:Object.fromEntries(Object.entries(r.dataSource||{}).map(([D,N])=>[D,N?.[b]??{}]))}),w=r=>({id:r.id,createdAt:r.createdAt,updatedAt:r.updatedAt,publishedAt:r.publishedAt,path:r.path,handler:r.handler,isPublic:r.isPublic??!0,params:r.params??[],enabledGenerate:r.enabledGenerate??!1,displayTemplateId:r.displayTemplateId,dataSource:r.dataSource}),u=R(m.map(r=>{const b=t.routes[r];return b&&w(b)})),l=R(t.supportedLocales.map(r=>r.locale).flatMap(r=>c.map(b=>{const D=t.pages[b];return D&&{locale:r,slug:D.slug,page:T(D,r)}}))),y=Le(),j=g.join(y,"pages");I.mkdirSync(j,{recursive:!0});const h=g.join(y,"components");I.mkdirSync(h,{recursive:!0});const f=g.join(y,"routes");I.mkdirSync(f,{recursive:!0});for(const{locale:r,slug:b,page:D}of l)await W(D,j,{getFilename:()=>`${te(b)||"index"}.${r}.yml`,exportAssets:e});for(const r of u)await W(r,f,{getFilename:()=>`${te(r.path)||"index"}.yml`,exportAssets:e});for(const r of p){const b=t.components[r]?.data;b&&await W(b,h,{getFilename:D=>`${D.name||"unnamed"}.${D.id}.yml`,exportAssets:e})}const S=g.join(y,".blocklet/pages/pages.config.yml");I.mkdirSync(g.dirname(S),{recursive:!0});const A={pages:R(c.map(r=>{const b=t.pages[r];return b&&{id:r,slug:b.slug}})),routes:R(m.map(r=>{const b=t.routes[r];return b&&{id:r,path:b.path}})),components:R(p.map(r=>{const b=t.components[r]?.data;return b&&{id:r,name:b.name}})),...o?{resources:{components:R(Object.keys(t.resources?.components||{}).filter(r=>p.includes(r)).map(r=>({id:r,name:t.resources?.components?.[r]?.component?.name})))}}:{},supportedLocales:t.supportedLocales,config:t.config};I.writeFileSync(S,x.stringify(A));const P=g.join(y,"config.source.json");if(n&&I.writeFileSync(P,JSON.stringify(n)),o){const r=g.join(y,"resources"),b=g.join(r,"components");I.mkdirSync(b,{recursive:!0});for(const V of Object.keys(t?.resources?.components??{}).filter(_=>p.includes(_))){const _=t.resources?.components?.[V]?.component;_&&await W(_,b,{getFilename:G=>`${G.name||"unnamed"}.${G.id}.yml`,exportAssets:e})}const D=g.join(y,"chunks");I.mkdirSync(D,{recursive:!0});const N=Ut();for(const V of Object.keys(t?.resources?.components??{}).filter(_=>p.includes(_))){const _=t.resources?.components?.[V]?.component;if(_&&_.renderer?.type==="react-component"){const G=_.renderer?.chunks??[];if(G?.length>0)for(const ie of G){const je=g.join(D,ie),ce=N?.[ie];try{ce&&I.existsSync(ce)&&!I.existsSync(je)&&I.copyFileSync(ce,je)}catch(Ye){d.logger.error(`copy chunk ${ie} error`,Ye.message)}}}}}return y}async function Ce(t,{importAssets:e,includeResources:s}={}){if(!I.existsSync(t))return null;let a,n=!1;try{I.lstatSync(t).isDirectory()?a=t:/\.(tgz|gz|tar)$/.test(t)&&(n=!0,a=Le(),await pt.x({file:t,C:a}));const o=X.globSync("**/.blocklet/pages/pages.config.yml",{cwd:a,absolute:!0}).at(0),i=o&&g.join(g.dirname(o),"../../pages"),c=o&&g.join(g.dirname(o),"../../components"),p=o&&g.join(g.dirname(o),"../../routes");if(!o)return null;const m=x.parse(I.readFileSync(o).toString()),k=(h,f,S)=>{let A=g.join(h,`${f}${S?`.${S}`:""}.yml`);return(!I.existsSync(A)||!I.lstatSync(A).isFile())&&(A=g.join(h,f,`index${S?`.${S}`:""}.yml`),!I.existsSync(A)||!I.lstatSync(A))?null:x.parse(I.readFileSync(A).toString())},T=(h,f)=>{try{const S=X.globSync(`*.${f}.yml`,{cwd:h,absolute:!0})[0];return S?x.parse(I.readFileSync(S).toString()):null}catch(S){d.logger.error("parse component error",S)}return null},w=(h,f)=>{let S=g.join(h,`${f}.yml`);return(!I.existsSync(S)||!I.lstatSync(S).isFile())&&(S=g.join(h,f,"index.yml"),!I.existsSync(S)||!I.lstatSync(S))?null:x.parse(I.readFileSync(S).toString())},u=R(m.pages.map(({slug:h})=>{const f=R(m.supportedLocales.map(({locale:P})=>{const r=i?k(i,te(h),P):void 0;if(r)return{locale:P,page:r};const b=i?k(i,h,P):void 0;return b&&{locale:P,page:b}})),S=f[0]?.page;if(!S)return null;const A=S.sections.map(Qe.unzipSection);return{id:S.id||Te.nextId(),createdAt:S.createdAt,updatedAt:S.updatedAt,publishedAt:S.publishedAt,isPublic:S.isPublic??!0,templateConfig:S.templateConfig,slug:h,sections:Object.fromEntries(A.map(P=>[P.id,P])),sectionIds:A.map(P=>P.id),locales:Object.fromEntries(f.map(({locale:P,page:r})=>[P,r.meta])),dataSource:S.dataSource?Object.fromEntries([...new Set(f.flatMap(({page:P})=>Object.keys(P.dataSource??{})))].map(P=>[P,Object.fromEntries(f.map(({locale:r,page:b})=>{const D=b.dataSource?.[P];return[r,D||{}]}))])):Object.fromEntries([...new Set(f.flatMap(({page:P})=>P.sections.map(r=>r.id)))].map(P=>[P,Object.fromEntries(f.map(({locale:r,page:b})=>{const D=b.dataSource?.[P];if(D)return[r,D];const N=b.sections.find(V=>V.id===P);return[r,N?.properties||{}]}))]))}})),l=R(m?.routes?.map(({path:h})=>{const f=p?w(p,te(h)):void 0;return{...f,id:f?.id||Te.nextId(),createdAt:f?.createdAt??new Date().toISOString(),updatedAt:f?.updatedAt??new Date().toISOString(),publishedAt:new Date(0).toISOString(),path:f?.path??`/${f?.id}`,params:f?.params,handler:f?.handler??"Pages Kit",isPublic:f?.isPublic??!0,enabledGenerate:f?.enabledGenerate??!1,displayTemplateId:f?.displayTemplateId??void 0,dataSource:f?.dataSource??{}}})??[]),y=c?R(m.components?.map(({id:h})=>T(c,h))??[]):[];if(e){const h=(...f)=>{d.logger.info(`[${n?g.basename(t):g.basename(g.join(t,"../../../../"))}] importAssets:`,...f)};try{h("wait image-bin api ready"),await ht.default({resources:[`${Ie.getComponentWebEndpoint(d.IMAGE_BIN_NAME)}/api/sdk/uploads`],validateStatus:A=>A>=200&&A<=500}),h("image-bin api is ready");const f={},S={};h("start to upload assets"),await Promise.allSettled([ve(y,f,{getFilePath:A=>c&&g.join(c,A),onFinish:A=>{h(`upload ${A.length} component assets`)}}),ve(u,S,{getFilePath:(A,P)=>{const r=Ee.default(u,P.slice(0,1));return i&&g.join(i,g.dirname(r.slug),A)},onFinish:A=>{h(`upload ${A.length} page assets`)}})]),h("upload assets done"),ye.clear(),global.gc&&global.gc()}catch(f){h("Error during asset import:",f)}}const j={};if(s){const h=o&&g.join(g.dirname(o),"../../resources/components"),f=R(m.resources?.components?.map(({id:S})=>T(h,S))??[]);f.length>0&&(j.components=Object.fromEntries(f.map((S,A)=>[S.id,{index:A,component:S}])))}return{supportedLocales:m.supportedLocales,pageIds:u.map(h=>h.id),components:Object.fromEntries(y.map((h,f)=>[h.id,{index:f,data:h}])),pages:Object.fromEntries(u.map(h=>[h.id,h])),config:m.config||{},resources:j,routeIds:l.map(h=>h.id),routes:Object.fromEntries(l.map(h=>[h.id,h])),dataSourceIds:[],dataSources:{}}}finally{n&&a&&I.rmSync(a,{force:!0,recursive:!0})}}async function Se(t,e,{routes:s,mergeMode:a="byUpdateTime",deleteRoutes:n=!1,publishMode:o=void 0}={}){try{o&&d.clearPreloadComponentsCacheByMode(o)}catch(w){d.logger.error("clear preload page cache error",{error:w})}const{pages:i,pageIds:c,routeIds:p,routes:m,supportedLocales:k}=t;if(o==="production"){let w=s??[],u=null;for(const l of p??[]){const y=m?.[l];if(y?.params&&y?.params.length>0&&y?.paramsOptions&&y?.paramsOptions.length>0){const j=Q.generateParamCombinations({basePath:y.path,params:y.params,routeId:y.id,paramsOptions:y.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]}),h=Object.fromEntries(j.map(f=>[`${l}-${f.paramOptionIds.join("-")}`,f]));u={...u||{},...h},s||(w=[...w,...j.map(f=>`${l}-${f.paramOptionIds.join("-")}`)])}else s||w.push(l)}d.logger.info("routeIds to be published: ",w);for(const l of w){let y=l;if(y.includes("-")){const[f]=y.split("-");y=f}const j=m?.[y];if(!j){const f=e.pageIds.indexOf(y);f!==-1&&n&&(e.pageIds.splice(f,1),delete e.pages[y]);for(const S of e.pageIds)S.includes(`${y}-`)&&(e.pageIds.splice(e.pageIds.indexOf(S),1),delete e.pages[S]);d.logger.info("delete main route page",y);continue}if(l.includes("-")&&!u?.[l]){const f=e.pageIds.indexOf(l);f!==-1&&n&&(e.pageIds.splice(f,1),delete e.pages[l]),d.logger.info("delete page",l);continue}if(!j.displayTemplateId){d.logger.info("no display template",l);continue}const h=i[j.displayTemplateId];if(!h){d.logger.info("no template page",l);continue}if(e.pageIds.includes(l)){if(d.logger.info("has need update page",l),a==="replace")e.pages[l]=ue({page:h,route:j,state:t,routeId:l,routePathInfo:u?.[l]}),d.logger.info("replace page",l);else if(a==="byUpdateTime"){const f=e.pages[j.id];(!f||j.updatedAt&&j.updatedAt>f.updatedAt)&&(e.pages[l]=ue({page:h,route:j,state:t,routeId:l,routePathInfo:u?.[l]}),d.logger.info("replace page by update time",l))}}else e.pageIds.push(l),e.pages[l]=ue({page:h,route:j,state:t,routeId:l,routePathInfo:u?.[l]}),d.logger.info("add page",l)}if(n&&!s)for(const l of e.pageIds)w?.includes(l)||(delete e.pages[l],d.logger.info("delete page",l)),e.pageIds=[...e.pageIds].filter(y=>w?.includes(y))}else{for(const w of c){const u=i[w];if(u)if(e.pageIds.includes(u.id)){if(a==="replace")e.pages[u.id]=u;else if(a==="byUpdateTime"){const l=e.pages[u.id];(!l||u.updatedAt&&u.updatedAt>l.updatedAt)&&(e.pages[u.id]=u)}}else e.pageIds.push(u.id),e.pages[u.id]=u}for(const w of p){const u=m[w];if(u)if(e.routeIds.includes(u.id)){if(a==="replace")e.routes[u.id]=u;else if(a==="byUpdateTime"){const l=e.routes[u.id];(!l||u.updatedAt&&u.updatedAt>l.updatedAt)&&(e.routes[u.id]=u)}}else e.routeIds.push(u.id),e.routes[u.id]=u}}if(e.supportedLocales.splice(0,e.supportedLocales.length),e.supportedLocales.push(...ft.default(k)),n)for(const w of Object.keys(e.components))delete e.components[w];let T=JSON.parse(JSON.stringify(t.components));T=Object.fromEntries(await Promise.all(Object.entries(T).map(async([w,u])=>{const l=await Fe(u?.data);return[w,{...u,data:l}]}))),Object.assign(e.components,T),Object.assign(e.config,JSON.parse(JSON.stringify(t.config))),we.default(t.resources.components)||(e.resources.components=JSON.parse(JSON.stringify(t.resources.components||{})))}const Fe=d.memoizeWithFs(async t=>{if(!we.default(t?.properties))return t;if(t?.renderer?.type==="react-component"){const{script:e,PROPERTIES_SCHEMA:s}=t?.renderer||{};if(s||e&&e.includes("PROPERTIES_SCHEMA"))try{const a=await d.getExportSchemaValueFromCode(e??"","PROPERTIES_SCHEMA",t.id,s);a&&a.length>0&&t&&(t.properties={},a.forEach((n,o)=>{t?.properties&&(t.properties[n.id]={index:o,data:n})}))}catch(a){d.logger.error("getPropertiesFromCode error",{componentId:t.id,name:t.name},{error:a})}}return t},{subdir:"getPropertiesFromCode"});let se,K,ne,oe;const qe=()=>Ie.getResources({types:[{did:Pe,type:ge},{did:bt,type:ge}]}),Ut=()=>{const t=qe(),e={};return t.forEach(s=>{const a=X.globSync("**/.blocklet/pages/pages.config.yml",{cwd:s.path,absolute:!0}).at(0),n=a&&g.join(g.dirname(a),"../../chunks");if(n&&I.existsSync(n)){const o=I.readdirSync(n);for(const i of o)e[i]=g.join(n,i)}}),e};function xe(){return se=(async()=>{const t=qe();K=(await Promise.all(t.map(async s=>{const a=s.path?await Ce(s.path,{importAssets:!1}):void 0;return a?{blockletId:s.did,state:a,blockletTitle:s.title}:void 0}))).filter(s=>!!s),ne=K.reduce((s,a)=>Object.assign(s,Object.fromEntries(Object.values(a.state.pages).map(n=>n?[n?.id,{page:n,blockletId:a.blockletId}]:[]))),{});const e=K.reduce((s,a)=>Object.assign(s,Object.fromEntries(Object.values(a.state.components).map(n=>[n.data.id,{blockletId:a.blockletId,component:n.data}]))),{});oe=Object.fromEntries(await Promise.all(Object.entries(e).map(async([s,a])=>{const n=await Fe(a.component);return[s,{...a,component:n}]})))})(),se}function Be(t){const e=Re.default(async()=>{await xe().catch(s=>{d.logger.error("load resource states error",{error:s})}),await t?.({states:K,pages:ne,components:oe})},3e3,{leading:!1,trailing:!0});return e(),E.default.events.on(E.default.Events.componentAdded,e),E.default.events.on(E.default.Events.componentRemoved,e),E.default.events.on(E.default.Events.componentStarted,e),E.default.events.on(E.default.Events.componentStopped,e),E.default.events.on(E.default.Events.componentUpdated,e),E.default.events.on(me,e),()=>{E.default.events.off(E.default.Events.componentAdded,e),E.default.events.off(E.default.Events.componentRemoved,e),E.default.events.off(E.default.Events.componentStarted,e),E.default.events.off(E.default.Events.componentStopped,e),E.default.events.off(E.default.Events.componentUpdated,e),E.default.events.off(me,e)}}const Ve=Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"),Ge=Symbol.for("GLOBAL_ENV_UPDATE_LISTENER_KEY"),re=globalThis;re[Ve]?.();re[Ve]=Be(async({pages:t,components:e})=>{const s=await O.getProjectIds();d.logger.info(`start update resource states projects(${s.length})`,s),await Promise.race([new Promise(a=>{setTimeout(()=>{a({})},30*1e3)}),Promise.all(s.map(async a=>{ze({projectId:a,pages:t,components:e})}))]).catch(a=>{d.logger.error("update resource states failed:",a)})});re[Ge]?.();re[Ge]=()=>{const t=()=>{O.pageUrlMapCache.clear(),d.logger.info("[Cache CLEAR ALL] clear all page url map cache by env update")};return E.default.events.on(E.default.Events.envUpdate,t),()=>{E.default.events.off(E.default.Events.envUpdate,t)}};O.startPeriodicCheck();process.on("beforeExit",()=>{O.stopPeriodicCheck()});process.on("SIGINT",()=>{O.stopPeriodicCheck(),process.exit(0)});process.on("SIGTERM",()=>{O.stopPeriodicCheck(),process.exit(0)});async function ze({projectId:t,pages:e,components:s}){const a=O.sharedInstances[t];if(!a){d.logger.info(`projectId: ${t} not found in sharedInstances`);return}if(a.syncedStore.resources.pages=e,(await L.findByPk(t))?.useAllResources)a.syncedStore.resources.components=s;else{const i=(await Ae.findAll({where:{projectId:t}})).map(p=>p.componentId),c=Object.fromEntries(Object.entries(s||{}).filter(([p])=>i.includes(p)));a.syncedStore.resources.components=c}d.logger.info(`update [${t}] resource states:`,{pages:Object.keys(a.syncedStore.resources.pages||{}).length,components:Object.keys(a.syncedStore.resources.components||{}).length})}async function Mt(t){return ze({projectId:t,pages:ne,components:oe})}async function Nt(){d.logger.info("trigger reload all project resource"),E.default.events.emit(me)}async function Ft({ensureLoaded:t=!0}={}){return t&&(se??=xe(),await se),{states:K,pages:ne,components:oe}}exports.COMPONENT_DID=Pe;exports.PUBLISH_MODES=_t;exports.Project=L;exports.RESOURCE_TYPE=ge;exports.SITE_STATE_PATH=q;exports.STATE_MODES=Lt;exports.SiteState=O;exports.downloadAsset=$e;exports.downloadAssets=Ue;exports.fromPackage=Ce;exports.getDefaultState=_e;exports.getResourceStates=Ft;exports.initPackResourceStates=Be;exports.mergeState=Se;exports.toPackage=Ne;exports.triggerReloadAllProjectResource=Nt;exports.updateResourceStatesByProjectId=Mt;
@@ -1 +1 @@
1
- "use strict";const g=require("./chunks/components-CacZMc0_.js"),c=require("./chunks/site-state-BkjuFb4-.js"),F=require("express"),L=require("fs"),J=require("joi"),X=require("lodash/groupBy"),W=require("lodash/sortBy"),B=require("path"),G=require("@blocklet/sdk/lib/middlewares/auth"),K=require("@blocklet/sdk/lib/component"),m=e=>e&&e.__esModule?e:{default:e},u=m(L),f=m(J),C=m(X),Y=m(W),D=m(B),k=m(G),$=async(e,t,o)=>{try{const{projectId:s}=e.params;if(!s)return o();const n=await c.Project.findByPk(s);if(!n)return t?.status(404).json({error:"Project not found"});const r=e.user?.did,a=e.user?.role||"UNKNOWN_ROLE";if(!r)return t?.status(401).json({error:"Authentication required"});if(g.isMultiTenant()){const P=n.createdBy===r,y=g.getMultiTenantAllProjectAccessPassports()?.includes?.(a);if(!P&&!y)return t?.status(403).json({error:"No permission to access this project in multi-tenant mode"})}else if(!["owner","admin","pagesEditor"].includes(a))return t?.status(403).json({error:"No permission to access this project in single-tenant mode"});e.project=n,e.projectId=s,o()}catch(s){g.logger.error("Project middleware error:",s),t?.status(400).json({error:"Internal server error"})}};function b(e,t){return new Promise((o,s)=>{const n=u.default.createReadStream(e),r=u.default.createWriteStream(t);n.on("error",s),r.on("error",s),r.on("finish",o),n.pipe(r)})}async function N(e,t){await u.default.promises.mkdir(t,{recursive:!0});const o=await u.default.promises.readdir(e,{withFileTypes:!0});for(const s of o){const n=D.default.join(e,s.name),r=D.default.join(t,s.name);s.isDirectory()?await N(n,r):await b(n,r)}}async function z(e,t){(await u.default.promises.stat(e)).isDirectory()?await N(e,t):await b(e,t)}const h=(e,t,o)=>g.isMultiTenant()?k.default()(e,t,o):k.default({roles:["owner","admin","pagesEditor"]})(e,t,o),H=(e,t)=>{const o=K.getResourceExportDir({projectId:e,releaseId:t});return B.join(o,c.COMPONENT_DID,c.RESOURCE_TYPE)},w=F.Router(),T="@page",U="@component",j=":",R="ALL",q="@project",v=({pageId:e,projectId:t})=>[T,t,e].join(j),Q=e=>{const[t,o,s]=e.split(j);if(t===T)return{pageId:s,projectId:o}},x=({componentId:e,projectId:t})=>[U,t,e].join(j),V=e=>{const[t,o,s]=e.split(j);if(t===U)return{componentId:s,projectId:o}},Z=e=>[q,e].join(j),ee=e=>{const[t,o]=e.split(j);if(t===q)return o},te=e=>{try{return JSON.parse(e)}catch{}return{}};async function A(e){const t=await c.SiteState.getStateByProjectId(e,"production"),o=await c.Project.findByPk(e),s=t.pageIds.map(r=>{const a=t.pages[r];if(a)return{id:v({pageId:r,projectId:e}),name:a.slug}}).filter(Boolean),n=Y.default(Object.values(t.components),r=>r.index).map(({data:r})=>({id:x({componentId:r.id,projectId:e}),name:r.name||r.id}));return{id:Z(e),name:o?.name||"Unnamed Project",children:[{id:v({pageId:R,projectId:e}),name:"Pages",children:s},{id:x({componentId:R,projectId:e}),name:"Components",children:n}]}}w.get("/resources",h,async(e,t)=>{const{projectId:o}=te(e.query.resourcesParams);if(o){e.params={...e.params,projectId:o},await $(e,t,()=>{});const r=await A(o);t.json({resources:[r]});return}const s=await c.Project.findAll({where:{}}),n=await Promise.all(s.map(r=>A(r.id)));t.json({resources:n})});const oe=f.default.object({projectId:f.default.string().required().min(1),releaseId:f.default.string().allow(""),resources:f.default.array().items(f.default.string()).required(),locale:f.default.string().allow("")});w.post("/resources",h,async(e,t)=>{const{resources:o,projectId:s,releaseId:n}=await oe.validateAsync(e.body),r="production",a=[],P=[];for(const i of o){if(ee(i))continue;const{pageId:d,projectId:_}=Q(i)||{};if(d)d===R||d&&_&&a.push({pageId:d,projectId:_});else{const{componentId:I,projectId:p}=V(i)||{};I===R||I&&p&&P.push({componentId:I,projectId:p})}}const y=C.default(a,"projectId"),O=C.default(P,"projectId"),M=new Set([...Object.keys(y),...Object.keys(O)]),E=H(s,n);u.default.rmSync(E,{recursive:!0,force:!0}),u.default.mkdirSync(E,{recursive:!0});for(const i of M){const d=await c.SiteState.getStateByProjectId(i,r),_=y[i],I=O[i],p=_?.map(l=>l.pageId),S=I?.map(l=>l.componentId);if(p?.length||S?.length){const l=await c.toPackage(d,{exportAssets:!0,pageIds:p,componentIds:S});await z(l,E),u.default.rmSync(l,{recursive:!0,force:!0})}g.logger.info(`Exported resources for project ${i}`,{pageIds:p,componentIds:S})}t.json({})});w.get("/all-resources",h,async(e,t)=>{const{states:o}=await c.getResourceStates(),s=o?.map(n=>{const r={blockletId:n.blockletId,blockletTitle:n.blockletTitle,components:{}};if(n.state.components&&(r.components=n.state.components),Object.keys(r.components).length!==0)return r}).filter(Boolean);t.json(s)});module.exports=w;
1
+ "use strict";const g=require("./chunks/components-CacZMc0_.js"),c=require("./chunks/site-state-Vc48a38-.js"),F=require("express"),L=require("fs"),J=require("joi"),X=require("lodash/groupBy"),W=require("lodash/sortBy"),B=require("path"),G=require("@blocklet/sdk/lib/middlewares/auth"),K=require("@blocklet/sdk/lib/component"),m=e=>e&&e.__esModule?e:{default:e},u=m(L),f=m(J),C=m(X),Y=m(W),D=m(B),k=m(G),$=async(e,t,o)=>{try{const{projectId:s}=e.params;if(!s)return o();const n=await c.Project.findByPk(s);if(!n)return t?.status(404).json({error:"Project not found"});const r=e.user?.did,a=e.user?.role||"UNKNOWN_ROLE";if(!r)return t?.status(401).json({error:"Authentication required"});if(g.isMultiTenant()){const P=n.createdBy===r,y=g.getMultiTenantAllProjectAccessPassports()?.includes?.(a);if(!P&&!y)return t?.status(403).json({error:"No permission to access this project in multi-tenant mode"})}else if(!["owner","admin","pagesEditor"].includes(a))return t?.status(403).json({error:"No permission to access this project in single-tenant mode"});e.project=n,e.projectId=s,o()}catch(s){g.logger.error("Project middleware error:",s),t?.status(400).json({error:"Internal server error"})}};function b(e,t){return new Promise((o,s)=>{const n=u.default.createReadStream(e),r=u.default.createWriteStream(t);n.on("error",s),r.on("error",s),r.on("finish",o),n.pipe(r)})}async function N(e,t){await u.default.promises.mkdir(t,{recursive:!0});const o=await u.default.promises.readdir(e,{withFileTypes:!0});for(const s of o){const n=D.default.join(e,s.name),r=D.default.join(t,s.name);s.isDirectory()?await N(n,r):await b(n,r)}}async function z(e,t){(await u.default.promises.stat(e)).isDirectory()?await N(e,t):await b(e,t)}const h=(e,t,o)=>g.isMultiTenant()?k.default()(e,t,o):k.default({roles:["owner","admin","pagesEditor"]})(e,t,o),H=(e,t)=>{const o=K.getResourceExportDir({projectId:e,releaseId:t});return B.join(o,c.COMPONENT_DID,c.RESOURCE_TYPE)},w=F.Router(),T="@page",U="@component",j=":",R="ALL",q="@project",v=({pageId:e,projectId:t})=>[T,t,e].join(j),Q=e=>{const[t,o,s]=e.split(j);if(t===T)return{pageId:s,projectId:o}},x=({componentId:e,projectId:t})=>[U,t,e].join(j),V=e=>{const[t,o,s]=e.split(j);if(t===U)return{componentId:s,projectId:o}},Z=e=>[q,e].join(j),ee=e=>{const[t,o]=e.split(j);if(t===q)return o},te=e=>{try{return JSON.parse(e)}catch{}return{}};async function A(e){const t=await c.SiteState.getStateByProjectId(e,"production"),o=await c.Project.findByPk(e),s=t.pageIds.map(r=>{const a=t.pages[r];if(a)return{id:v({pageId:r,projectId:e}),name:a.slug}}).filter(Boolean),n=Y.default(Object.values(t.components),r=>r.index).map(({data:r})=>({id:x({componentId:r.id,projectId:e}),name:r.name||r.id}));return{id:Z(e),name:o?.name||"Unnamed Project",children:[{id:v({pageId:R,projectId:e}),name:"Pages",children:s},{id:x({componentId:R,projectId:e}),name:"Components",children:n}]}}w.get("/resources",h,async(e,t)=>{const{projectId:o}=te(e.query.resourcesParams);if(o){e.params={...e.params,projectId:o},await $(e,t,()=>{});const r=await A(o);t.json({resources:[r]});return}const s=await c.Project.findAll({where:{}}),n=await Promise.all(s.map(r=>A(r.id)));t.json({resources:n})});const oe=f.default.object({projectId:f.default.string().required().min(1),releaseId:f.default.string().allow(""),resources:f.default.array().items(f.default.string()).required(),locale:f.default.string().allow("")});w.post("/resources",h,async(e,t)=>{const{resources:o,projectId:s,releaseId:n}=await oe.validateAsync(e.body),r="production",a=[],P=[];for(const i of o){if(ee(i))continue;const{pageId:d,projectId:_}=Q(i)||{};if(d)d===R||d&&_&&a.push({pageId:d,projectId:_});else{const{componentId:I,projectId:p}=V(i)||{};I===R||I&&p&&P.push({componentId:I,projectId:p})}}const y=C.default(a,"projectId"),O=C.default(P,"projectId"),M=new Set([...Object.keys(y),...Object.keys(O)]),E=H(s,n);u.default.rmSync(E,{recursive:!0,force:!0}),u.default.mkdirSync(E,{recursive:!0});for(const i of M){const d=await c.SiteState.getStateByProjectId(i,r),_=y[i],I=O[i],p=_?.map(l=>l.pageId),S=I?.map(l=>l.componentId);if(p?.length||S?.length){const l=await c.toPackage(d,{exportAssets:!0,pageIds:p,componentIds:S});await z(l,E),u.default.rmSync(l,{recursive:!0,force:!0})}g.logger.info(`Exported resources for project ${i}`,{pageIds:p,componentIds:S})}t.json({})});w.get("/all-resources",h,async(e,t)=>{const{states:o}=await c.getResourceStates(),s=o?.map(n=>{const r={blockletId:n.blockletId,blockletTitle:n.blockletTitle,components:{}};if(n.state.components&&(r.components=n.state.components),Object.keys(r.components).length!==0)return r}).filter(Boolean);t.json(s)});module.exports=w;
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("./chunks/components-CacZMc0_.js");const e=require("./chunks/site-state-BkjuFb4-.js"),u=require("@blocklet/pages-kit/utils/common");require("@blocklet/pages-kit/utils/page-model");require("@blocklet/pages-kit/utils/property");require("@blocklet/pages-kit/utils/route");require("@blocklet/sdk/lib/component");require("@blocklet/sdk/lib/config");require("@reactivedata/reactive");require("@syncedstore/core");require("fs");require("glob");require("lib0/decoding");require("lib0/encoding");require("lodash/cloneDeep");require("lodash/debounce");require("lodash/get");require("lodash/isEmpty");require("lodash/set");require("lodash/union");require("lru-cache");require("p-limit");require("path");require("sequelize");require("stream/promises");require("tar");require("ufo");require("wait-on");require("y-protocols/awareness");require("y-protocols/sync");require("yaml");require("yjs");const t=require("@blocklet/pages-kit/types/state");exports.PUBLISH_MODES=e.PUBLISH_MODES;exports.SITE_STATE_PATH=e.SITE_STATE_PATH;exports.STATE_MODES=e.STATE_MODES;exports.default=e.SiteState;exports.downloadAsset=e.downloadAsset;exports.downloadAssets=e.downloadAssets;exports.fromPackage=e.fromPackage;exports.getDefaultState=e.getDefaultState;exports.getResourceStates=e.getResourceStates;exports.initPackResourceStates=e.initPackResourceStates;exports.mergeState=e.mergeState;exports.toPackage=e.toPackage;exports.triggerReloadAllProjectResource=e.triggerReloadAllProjectResource;Object.defineProperty(exports,"nextId",{enumerable:!0,get:()=>u.nextId});Object.keys(t).forEach(r=>{r!=="default"&&!Object.prototype.hasOwnProperty.call(exports,r)&&Object.defineProperty(exports,r,{enumerable:!0,get:()=>t[r]})});
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("./chunks/components-CacZMc0_.js");const e=require("./chunks/site-state-Vc48a38-.js"),u=require("@blocklet/pages-kit/utils/common");require("@blocklet/pages-kit/utils/page-model");require("@blocklet/pages-kit/utils/property");require("@blocklet/pages-kit/utils/route");require("@blocklet/sdk/lib/component");require("@blocklet/sdk/lib/config");require("@reactivedata/reactive");require("@syncedstore/core");require("fs");require("glob");require("lib0/decoding");require("lib0/encoding");require("lodash/cloneDeep");require("lodash/debounce");require("lodash/get");require("lodash/isEmpty");require("lodash/set");require("lodash/union");require("lru-cache");require("p-limit");require("path");require("sequelize");require("stream/promises");require("tar");require("ufo");require("wait-on");require("y-protocols/awareness");require("y-protocols/sync");require("yaml");require("yjs");const t=require("@blocklet/pages-kit/types/state");exports.PUBLISH_MODES=e.PUBLISH_MODES;exports.SITE_STATE_PATH=e.SITE_STATE_PATH;exports.STATE_MODES=e.STATE_MODES;exports.default=e.SiteState;exports.downloadAsset=e.downloadAsset;exports.downloadAssets=e.downloadAssets;exports.fromPackage=e.fromPackage;exports.getDefaultState=e.getDefaultState;exports.getResourceStates=e.getResourceStates;exports.initPackResourceStates=e.initPackResourceStates;exports.mergeState=e.mergeState;exports.toPackage=e.toPackage;exports.triggerReloadAllProjectResource=e.triggerReloadAllProjectResource;exports.updateResourceStatesByProjectId=e.updateResourceStatesByProjectId;Object.defineProperty(exports,"nextId",{enumerable:!0,get:()=>u.nextId});Object.keys(t).forEach(r=>{r!=="default"&&!Object.prototype.hasOwnProperty.call(exports,r)&&Object.defineProperty(exports,r,{enumerable:!0,get:()=>t[r]})});
@@ -434,11 +434,7 @@ class C extends N.Doc {
434
434
  let s = C.sharedInstances[e];
435
435
  return s || (s = new C({
436
436
  path: E(q, e)
437
- }), C.sharedInstances[e] = s, qe({
438
- projectId: e,
439
- pages: ne,
440
- components: ie
441
- }), s);
437
+ }), C.sharedInstances[e] = s, s);
442
438
  }
443
439
  // 轻量级 production 状态获取,不加载 draft 数据
444
440
  static async getProductionState(e) {
@@ -1558,10 +1554,17 @@ async function qe({
1558
1554
  components: Object.keys(a.syncedStore.resources.components || {}).length
1559
1555
  });
1560
1556
  }
1561
- async function ks() {
1557
+ async function ks(t) {
1558
+ return qe({
1559
+ projectId: t,
1560
+ pages: ne,
1561
+ components: ie
1562
+ });
1563
+ }
1564
+ async function Ts() {
1562
1565
  f.info("trigger reload all project resource"), I.events.emit(he);
1563
1566
  }
1564
- async function Ts({
1567
+ async function Ds({
1565
1568
  ensureLoaded: t = !0
1566
1569
  } = {}) {
1567
1570
  return t && (re ??= ze(), await re), { states: Q, pages: ne, components: ie };
@@ -1577,10 +1580,11 @@ export {
1577
1580
  Gt as d,
1578
1581
  zt as e,
1579
1582
  Jt as f,
1580
- Ts as g,
1583
+ Ds as g,
1581
1584
  Be as h,
1582
1585
  Ht as i,
1583
- ks as j,
1586
+ Ts as j,
1584
1587
  je as m,
1585
- Kt as t
1588
+ Kt as t,
1589
+ ks as u
1586
1590
  };
@@ -1,5 +1,5 @@
1
1
  import { i as A, a as M, l as b } from "./chunks/components-BWQM8y6L.js";
2
- import { P as w, C as J, R as X, S as x, t as W, g as G } from "./chunks/site-state-BMW2lUR1.js";
2
+ import { P as w, C as J, R as X, S as x, t as W, g as G } from "./chunks/site-state-Dt2__Byi.js";
3
3
  import { Router as K } from "express";
4
4
  import a from "fs";
5
5
  import m from "joi";
@@ -1,6 +1,6 @@
1
1
  import "./chunks/components-BWQM8y6L.js";
2
- import { c as b, a as h, b as B, S as L, e as U, f as q, h as v, d as y, g as z, i as C, m as F, t as G, j as J } from "./chunks/site-state-BMW2lUR1.js";
3
- import { nextId as N } from "@blocklet/pages-kit/utils/common";
2
+ import { c as O, a as b, b as h, S as y, e as L, f as U, h as q, d as v, g as z, i as C, m as F, t as G, j as J, u as K } from "./chunks/site-state-Dt2__Byi.js";
3
+ import { nextId as Q } from "@blocklet/pages-kit/utils/common";
4
4
  import "@blocklet/pages-kit/utils/page-model";
5
5
  import "@blocklet/pages-kit/utils/property";
6
6
  import "@blocklet/pages-kit/utils/route";
@@ -32,18 +32,19 @@ import "yaml";
32
32
  import "yjs";
33
33
  export * from "@blocklet/pages-kit/types/state";
34
34
  export {
35
- b as PUBLISH_MODES,
36
- h as SITE_STATE_PATH,
37
- B as STATE_MODES,
38
- L as default,
39
- U as downloadAsset,
40
- q as downloadAssets,
41
- v as fromPackage,
42
- y as getDefaultState,
35
+ O as PUBLISH_MODES,
36
+ b as SITE_STATE_PATH,
37
+ h as STATE_MODES,
38
+ y as default,
39
+ L as downloadAsset,
40
+ U as downloadAssets,
41
+ q as fromPackage,
42
+ v as getDefaultState,
43
43
  z as getResourceStates,
44
44
  C as initPackResourceStates,
45
45
  F as mergeState,
46
- N as nextId,
46
+ Q as nextId,
47
47
  G as toPackage,
48
- J as triggerReloadAllProjectResource
48
+ J as triggerReloadAllProjectResource,
49
+ K as updateResourceStatesByProjectId
49
50
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/pages-kit-inner-components",
3
- "version": "0.6.10",
3
+ "version": "0.6.12",
4
4
  "description": "Pages Kit inner components library",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -69,22 +69,22 @@
69
69
  "url": "git+https://github.com/blocklet/pages-kit.git"
70
70
  },
71
71
  "dependencies": {
72
- "@arcblock/did-auth": "^1.20.15",
72
+ "@arcblock/did-auth": "^1.20.16",
73
73
  "@arcblock/did-auth-storage-nedb": "^1.7.1",
74
- "@arcblock/did-connect": "^3.0.22",
75
- "@arcblock/react-hooks": "^3.0.22",
76
- "@arcblock/ux": "^3.0.22",
77
- "@blocklet/ai-kit": "^0.2.0",
74
+ "@arcblock/did-connect": "^3.0.26",
75
+ "@arcblock/react-hooks": "^3.0.26",
76
+ "@arcblock/ux": "^3.0.26",
77
+ "@blocklet/ai-kit": "^0.2.1",
78
78
  "@blocklet/ai-runtime": "^0.4.276",
79
79
  "@blocklet/code-editor": "^0.4.276",
80
80
  "@blocklet/embed": "^0.2.5",
81
- "@blocklet/js-sdk": "^1.16.45",
81
+ "@blocklet/js-sdk": "^1.16.46",
82
82
  "@blocklet/logger": "1.16.44",
83
83
  "@blocklet/quickjs": "^0.4.276",
84
- "@blocklet/sdk": "^1.16.45",
84
+ "@blocklet/sdk": "^1.16.46",
85
85
  "@blocklet/studio-ui": "^0.4.276",
86
- "@blocklet/tracker": "^1.16.45",
87
- "@blocklet/ui-react": "^3.0.22",
86
+ "@blocklet/tracker": "^1.16.46",
87
+ "@blocklet/ui-react": "^3.0.26",
88
88
  "@blocklet/uploader": "^0.2.4",
89
89
  "@blocklet/uploader-server": "^0.2.2",
90
90
  "@emotion/cache": "^11.14.0",
@@ -105,9 +105,9 @@
105
105
  "@mui/styles": "^5.16.14",
106
106
  "@mui/utils": "^7.1.1",
107
107
  "@mui/x-date-pickers": "^8.6.0",
108
- "@ocap/client": "^1.20.15",
109
- "@ocap/mcrypto": "^1.20.15",
110
- "@ocap/wallet": "^1.20.15",
108
+ "@ocap/client": "^1.20.16",
109
+ "@ocap/mcrypto": "^1.20.16",
110
+ "@ocap/wallet": "^1.20.16",
111
111
  "@reactivedata/reactive": "^0.2.2",
112
112
  "@syncedstore/core": "^0.6.0",
113
113
  "@syncedstore/react": "^0.6.0",
@@ -203,8 +203,8 @@
203
203
  "yaml": "^2.5.0",
204
204
  "yjs": "^13.6.18",
205
205
  "zustand": "^4.5.5",
206
- "@blocklet/pages-kit": "^0.6.10",
207
- "@blocklet/pages-kit-block-studio": "^0.6.10"
206
+ "@blocklet/pages-kit": "^0.6.12",
207
+ "@blocklet/pages-kit-block-studio": "^0.6.12"
208
208
  },
209
209
  "devDependencies": {
210
210
  "@trivago/prettier-plugin-sort-imports": "^5.2.1",
@@ -1 +0,0 @@
1
- "use strict";const d=require("./components-CacZMc0_.js"),F=require("@syncedstore/core"),Je=require("yjs"),Ke=require("@blocklet/pages-kit/utils/data-source"),Q=require("@blocklet/pages-kit/utils/route"),He=require("lodash"),We=require("@blocklet/sdk/lib/config"),I=require("fs"),g=require("path"),Te=require("@blocklet/pages-kit/utils/common"),Qe=require("@blocklet/pages-kit/utils/page-model"),Xe=require("@blocklet/pages-kit/utils/property"),Ie=require("@blocklet/sdk/lib/component"),Ze=require("@reactivedata/reactive"),X=require("glob"),et=require("lib0/decoding"),tt=require("lib0/encoding"),st=require("lodash/cloneDeep"),at=require("lodash/debounce"),nt=require("lodash/get"),ot=require("lodash/isEmpty"),rt=require("lodash/set"),it=require("lodash/union"),be=require("lru-cache"),ct=require("p-limit"),C=require("sequelize"),lt=require("stream/promises"),pt=require("tar"),Y=require("ufo"),ut=require("wait-on"),z=require("y-protocols/awareness"),le=require("y-protocols/sync"),dt=require("yaml");require("sqlite3");require("@blocklet/pages-kit/types/state");const M=t=>t&&t.__esModule?t:{default:t};function ae(t){if(t&&t.__esModule)return t;const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const s in t)if(s!=="default"){const a=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,a.get?a:{enumerable:!0,get:()=>t[s]})}}return e.default=t,Object.freeze(e)}const $=ae(Je),E=M(We),pe=ae(et),v=ae(tt),ft=M(st),Re=M(at),Ee=M(nt),we=M(ot),De=M(rt),gt=M(it),mt=M(ct),ht=M(ut),x=ae(dt),yt=C.DataTypes.sqlite.DATE.parse;C.DataTypes.sqlite.DATE.parse=(t,e)=>typeof t=="number"?new Date(t):yt(t,e);const U=new C.Sequelize({dialect:"sqlite",storage:d.databaseUrl,benchmark:process.env.ENABLE_SEQUELIZE_BENCHMARK==="true",retry:{match:[/SQLITE_BUSY/],name:"query",max:10},logging:process.env.ENABLE_SEQUELIZE_LOGGING==="true"?console.log:!1});U.query("pragma journal_mode = WAL;");U.query("pragma synchronous = normal;");U.query("pragma journal_size_limit = 33554432;");U.query("pragma cache_size = -2000;");U.query("pragma mmap_size = 33554432;");process.on("SIGINT",async()=>{await U.close(),process.exit(0)});process.on("SIGTERM",async()=>{await U.close(),process.exit(0)});async function St(t,e){try{if(t.getDialect()!=="sqlite")return;const[s]=await t.query("SELECT 1");if(!s||s.length===0)return;await t.query("PRAGMA shrink_memory;")}catch(s){if(s.name==="SequelizeConnectionError"||s?.message&&/closed!/.test(s.message))return;console.error("Failed to cleanup SQLite memory",e,s)}}let fe=null;fe&&clearInterval(fe);fe=setInterval(async()=>{d.logger.info("Start cleanupSqliteMemory"),await St(U,d.databaseUrl),d.logger.info("End cleanupSqliteMemory")},60*1e3*10);class Ae extends C.Model{}Ae.init({id:{type:C.DataTypes.UUID,allowNull:!1,primaryKey:!0,defaultValue:C.DataTypes.UUIDV4},projectId:{type:C.DataTypes.UUID,allowNull:!1},componentId:{type:C.DataTypes.STRING,allowNull:!1}},{sequelize:U,tableName:"ProjectComponents",timestamps:!1});class L extends C.Model{static async getProjectByIdOrSlug(e){return L.findOne({where:{[C.Op.or]:[{id:e},{slug:e}]}})}}L.init({id:{type:C.DataTypes.UUID,defaultValue:C.DataTypes.UUIDV4,primaryKey:!0},name:{type:C.DataTypes.STRING,allowNull:!1},description:C.DataTypes.TEXT,createdAt:C.DataTypes.DATE,updatedAt:C.DataTypes.DATE,createdBy:{type:C.DataTypes.STRING,allowNull:!1},updatedBy:{type:C.DataTypes.STRING,allowNull:!1},slug:C.DataTypes.STRING,icon:C.DataTypes.STRING,pinnedAt:C.DataTypes.DATE,useAllResources:C.DataTypes.BOOLEAN,npmSecret:C.DataTypes.STRING,relatedBlocklets:{type:C.DataTypes.JSON,allowNull:!1,defaultValue:{},get(){const t=this.getDataValue("relatedBlocklets");if(typeof t=="object")return t??{};try{return t?JSON.parse(t):{}}catch(e){return d.logger.error("Failed to parse relatedBlocklets",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("relatedBlocklets",t?JSON.stringify(t):"{}")}catch(e){d.logger.error("Failed to set relatedBlocklets",{error:e,value:t}),this.setDataValue("relatedBlocklets","{}")}}},productionState:{type:C.DataTypes.JSON,allowNull:!1,defaultValue:{},get(){const t=this.getDataValue("productionState");if(typeof t=="object")return t??{};try{return t?JSON.parse(t):{}}catch(e){return d.logger.error("Failed to parse productionState",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("productionState",t?JSON.stringify(t):"{}")}catch(e){d.logger.error("Failed to set productionState",{error:e,value:t}),this.setDataValue("productionState","{}")}}}},{sequelize:U,paranoid:!0});L.hasMany(Ae,{foreignKey:"projectId",as:"components"});const It="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o",ge="page",me="trigger-reload-project-resource",Pe=It,bt="z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM";function Z(t){t.observeDeep(e=>{e.some(s=>s.changes.keys.has("updatedAt")||s.changes.keys.has("publishedAt"))||t.set("updatedAt",new Date().toISOString())})}function Le(){return I.mkdtempSync(g.join(E.default.env.dataDir,"tmp-"))}function ee(t,e,s=[]){return Array.isArray(t)?t.flatMap((a,n)=>ee(a,e,[...s,n])):typeof t=="object"?t===null?[]:Object.entries(t).flatMap(([a,n])=>ee(n,e,[...s,a])):e(t)?[s]:[]}function R(t){return t.filter(e=>e!=null)}function Et(t){t.pages&&Object.keys(t.pages).forEach(s=>{const a=F.getYjsValue(t.pages[s]);a&&a instanceof $.Map&&Z(a)});const e=F.getYjsValue(t.pages);e&&e instanceof $.Map&&e.observe(s=>{s.changes.keys.forEach((a,n)=>{if(a.action==="add"){const o=F.getYjsValue(t.pages[n]);o&&o instanceof $.Map&&Z(o)}})})}function wt(t){t.routes&&Object.keys(t.routes).forEach(s=>{const a=F.getYjsValue(t.routes?.[s]);a&&a instanceof $.Map&&Z(a)});const e=F.getYjsValue(t.routes);e&&e instanceof $.Map&&e.observe(s=>{s.changes.keys.forEach((a,n)=>{if(a.action==="add"){const o=F.getYjsValue(t.routes?.[n]);o&&o instanceof $.Map&&Z(o)}})})}function At(t,e){for(const s of e||Object.keys(t.routes||{})){let a=s,n=[];if(s.includes("-")){const[o,...i]=s.split("-");a=o,n=i||[]}if(t.routes?.[a]!==void 0){t.routes[a].publishedAt=new Date().toISOString();const o=t.routes[a];if(!o||!o.params||o.params.length===0)continue;if(s.includes("-")&&n.length>0){const i=Q.getRouteMetaDataByOptionIds(n,o);i&&(i.publishedAt=new Date().toISOString())}if(!e){const i=Q.generateParamCombinations({basePath:o.path,params:o.params,routeId:o.id,paramsOptions:o.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const c of i)c.routeMetaData??={},c.routeMetaData.publishedAt=new Date().toISOString()}}}}function ue({page:t,route:e,state:s,routeId:a,routePathInfo:n}){d.logger.info(`Executing datasource data assembly, routeId: ${a}, routePathInfo: ${JSON.stringify(n)}`);const o={...He.cloneDeep(t),id:a,slug:n?.path??e.path,createdAt:e.createdAt,updatedAt:n?.routeMetaData?.updatedAt??e.updatedAt,publishedAt:n?.routeMetaData?.publishedAt??e.publishedAt,isPublic:(n?.routeMetaData?.isPublic??e.isPublic)&&e.isPublic};for(const i of s.supportedLocales){if(e.dataSource){let c=e.id;n&&(c=n.paramOptionIds.join("-"));const p=e.dataSource.pathDataMappings?.[c]?.dataCache?.[i.locale]??e.dataSource.pathDataMappings?.[c]?.dataCache?.[s.config.defaultLocale||"en"];if(!p)continue;Ke.setPageDataSource(o,s,i.locale,p)}n&&n.routeMetaData&&(n.routeMetaData.publishedAt=new Date().toISOString())}return o}const Pt=30*60*1e3,B=new be.LRUCache({max:100,ttl:Pt});function Ot(t,e=[]){let s=0;const a=Array.from(B.keys()),n=[];for(const o of t){n.push(`page-html:prod:${o}:lang-path=none`);for(const i of e)n.push(`page-html:prod:/${i}${o}:lang-path=${i}`)}for(const o of a){const i=o.split(":lang-path=")[0]||"";for(const c of n){const m=(c.split(":lang-path=")[0]||"").replace(/\/:[^/]+/g,"");if(i.startsWith(m)){B.delete(o),s++,d.logger.info(`[Cache CLEAR] key: ${o}`);break}}}return d.logger.info(`[Cache CLEAR] cleared ${s} entries for patterns:`,n),s}function Ct({projectId:t,projectSlug:e,supportedLocales:s=[]}){let a=0;const n=Array.from(B.keys()),o=[];o.push(`page-html:prod:/${t}`),e&&e!==t&&o.push(`page-html:prod:/${e}`);for(const i of s)o.push(`page-html:prod:/${i}/${t}`),e&&e!==t&&(e!=="/"?o.push(`page-html:prod:/${i}/${e}`):o.push(`page-html:prod:/${i}`));for(const i of n)for(const c of o)if(i.startsWith(c)){B.delete(i),a++,d.logger.info(`[Cache CLEAR PROJECT] key: ${i}`);break}return d.logger.info(`[Cache CLEAR PROJECT] cleared ${a} entries for project ${t}${e?` (slug: ${e})`:""}`),a}function jt(){const t=B.size;return B.clear(),d.logger.info(`[Cache CLEAR ALL] cleared ${t} entries`),t}E.default.events.on(E.default.Events.envUpdate,jt);const{uploadToMediaKit:Tt}=require("@blocklet/uploader-server"),Oe=/^\w+(\w|-|\.)+\w+\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm)$/,J=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/i,ke=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/gi,Dt=1e4,kt=3e4,H=0,de=1,vt=0,Rt=1,he=E.default,q=g.join(process.env.BLOCKLET_DATA_DIR,"site-state"),Lt=["production","draft"],_t=["production"];function te(t){return t?.replace(/\//g,"|")||""}function _e(){const t=he.env.languages?.map(s=>({locale:s.code,name:s.name}))||[],e=t[0]?.locale||"en";return{pageIds:[],pages:{},routeIds:[],routes:{},dataSourceIds:[],dataSources:{},components:{},supportedLocales:t,config:{defaultLocale:e},resources:{}}}class O extends $.Doc{constructor(e){super(),this.options=e,I.existsSync(this.draftYjsFilePath)&&$.applyUpdate(this,I.readFileSync(this.draftYjsFilePath)),this.syncedStore=Ze.reactive(F.syncedStore({pages:{},pageIds:[],components:{},supportedLocales:[],config:{},resources:{},routeIds:[],routes:{},dataSourceIds:[],dataSources:{}},this)),this.initObserver(),this.on("update",this.updateHandler),this.awareness=new z.Awareness(this),this.awareness.on("update",this.awarenessChangeHandler),this.ensureDataStructure()}static RELEASE_DELAY=5*60*1e3;static PERIODIC_CHECK_INTERVAL=2*60*60*1e3;static sharedInstances={};static pageUrlMapCache=new be.LRUCache({max:100,ttl:1e3*60*60*24});static periodicCheckTimer;static safeDeleteProjectStateDir(e){if(!e)throw new Error("Should provide project context");try{const s=g.join(q,e),a=g.join(q,`@del-${e}`);I.renameSync(s,a)}catch(s){d.logger.error("Failed to safe delete project state dir:",s)}}static async getProjectIds(){return(await L.findAll({attributes:["id"],raw:!0}))?.map(e=>e.id)}static get projectIds(){return X.globSync("*/",{cwd:q,ignore:["@del-*","@tmp-*",".*","staging","production","@backup-*","undefined"]})}static get allShared(){return this.projectIds.map(e=>O.shared(e))}static shared(e){if(!e)throw new Error("Should provide project context");let s=O.sharedInstances[e];return s||(s=new O({path:g.join(q,e)}),O.sharedInstances[e]=s,ze({projectId:e,pages:ne,components:oe}),s)}static async getProductionState(e){const s=await L.findByPk(e,{attributes:["productionState"]});if(we.default(s?.productionState)){const a=g.join(q,e,"production"),n=await Ce(a,{includeResources:!0})??_e();if(!n?.config?.defaultLocale){n.config??={};const o=he.env.languages?.map(i=>({locale:i.code,name:i.name}))||[];n.config.defaultLocale=o[0]?.locale}return n}return s?.productionState}destroy(){this.cancelRelease(),this.save({flush:!0}),this.conns.forEach((s,a)=>this.closeConn(a)),this.awareness.destroy();const e=g.basename(this.options.path);delete O.sharedInstances[e],super.destroy()}initObserver(){Et(this.syncedStore),wt(this.syncedStore)}get draftYjsFilePath(){return g.join(this.options.path,"draft.yjs")}static async getStateByProjectId(e,s){if(s==="draft"){const a=O.shared(e);return JSON.parse(JSON.stringify(a.syncedStore))}return O.getProductionState(e)}async getState(e){if(e==="draft")return JSON.parse(JSON.stringify(this.syncedStore));const s=g.basename(this.options.path);return O.getProductionState(s)}async setState(e,s){const a=await Ne(s,{exportAssets:!1,includeResources:!0}),n=this.getPublishDir(e);if(I.mkdirSync(g.dirname(n),{recursive:!0}),I.rmSync(n,{force:!0,recursive:!0}),I.renameSync(a,n),e==="production"){const o=g.basename(this.options.path);O.pageUrlMapCache.delete(o),await L.update({productionState:{...s}},{where:{id:o}})}}getPublishDir(e){return g.join(this.options.path,e)}syncedStore;conns=new Map;awareness;releaseTimer;awarenessChangeHandler=({added:e,updated:s,removed:a},n)=>{const o=e.concat(s,a);if(n!==null){const p=this.conns.get(n);p&&(e.forEach(m=>{p.add(m)}),a.forEach(m=>{p.delete(m)}))}const i=v.createEncoder();v.writeVarUint(i,de),v.writeVarUint8Array(i,z.encodeAwarenessUpdate(this.awareness,o));const c=v.toUint8Array(i);this.conns.forEach((p,m)=>this.send(m,c))};updateHandler=e=>{const s=v.createEncoder();v.writeVarUint(s,H),le.writeUpdate(s,e);const a=v.toUint8Array(s);this.conns.forEach((n,o)=>this.send(o,a))};ensureDataStructure=()=>{const{supportedLocales:e,pages:s,pageIds:a,config:n,routes:o,routeIds:i}=this.syncedStore;{const c=new Set(Object.keys(s));let p=0;for(;p<a.length;){const m=a[p];c.has(m)?(c.delete(m),p++):a.splice(p,1)}}{const c=new Set(Object.keys(o));let p=0;for(;p<i.length;){const m=i[p];c.has(m)?(c.delete(m),p++):i.splice(p,1)}}e.splice(0,e.length),e.push(...he.env.languages.map(c=>({locale:c.code,name:c.name}))),n.defaultLocale=e[0]?.locale;{let c=0;const p=new Set;for(;c<e.length;){const{locale:m}=e[c];p.has(m)?e.splice(c,1):(c++,p.add(m))}}};send=(e,s)=>{e.readyState!==vt&&e.readyState!==Rt&&this.closeConn(e);try{e.send(s,a=>{a&&this.closeConn(e)})}catch{this.closeConn(e)}};closeConn=e=>{if(e.removeAllListeners(),this.conns.has(e)){const s=this.conns.get(e);this.conns.delete(e),s&&z.removeAwarenessStates(this.awareness,Array.from(s),null)}e.close(),this.checkAndScheduleRelease()};checkAndScheduleRelease(){this.conns.size===0&&this.scheduleRelease()}scheduleRelease(){this.cancelRelease();const e=g.basename(this.options.path);this.releaseTimer=setTimeout(()=>{d.logger.info(`[SiteState] releasing instance due to no active connections: ${e}`),this.conns.size===0&&(this.releaseTimer=void 0,this.destroy())},O.RELEASE_DELAY),d.logger.info(`[SiteState] scheduled release for project ${e} in ${O.RELEASE_DELAY/1e3}s`)}cancelRelease(){if(this.releaseTimer){clearTimeout(this.releaseTimer),this.releaseTimer=void 0;const e=g.basename(this.options.path);d.logger.info(`[SiteState] cancelled scheduled release for project ${e}`)}}autoSave=Re.default(()=>{I.mkdirSync(g.dirname(this.draftYjsFilePath),{recursive:!0}),I.writeFileSync(this.draftYjsFilePath,$.encodeStateAsUpdate(this))},Dt);save=({flush:e=!1}={})=>{this.autoSave(),e&&this.autoSave.flush()};publish=async({mode:e,routes:s})=>{const a=await this.getState("draft"),n=await this.getState("production");await Se(a,n,{routes:s,mergeMode:"replace",deleteRoutes:!0,publishMode:e}),n.config.publishedAt=new Date().getTime(),At(this.syncedStore,s),await this.setState(e,n),await this.clearPageCacheForRoutes(s,n)};mergeState=async(e,s)=>{const a=JSON.parse(JSON.stringify(s));e.config.fontFamily??={};const n=a.config?.fontFamily,o=e.config?.fontFamily;e.config.fontFamily.title=n?.title||o?.title,e.config.fontFamily.description=n?.description||o?.description,await new Promise((i,c)=>{this.transact(async()=>{try{const p=await Se(e,s);i(p)}catch(p){c(p)}})})};clearPageCacheForRoutes=async(e,s)=>{const a=g.basename(this.options.path),o=(await L.findByPk(a))?.slug||a;if(d.logger.info(`[SiteState] clearing page cache for project ${a}, routes:`,e||[]),!e||e.length===0){Ct({projectId:a,projectSlug:o,supportedLocales:s.supportedLocales.map(m=>m.locale)});return}const i=s.supportedLocales.map(m=>m.locale),c=[],p=e.filter(m=>s.pages[m]);for(const m of p){const T=s.pages[m].slug;o&&o!==a&&(o==="/"?c.push(T):c.push(`/${o}${T}`)),c.push(`/${a}${T}`)}if(d.logger.info(`[SiteState] clearing page cache for project ${a}, pathPatterns:`,c),c.length>0){const m=Ot(c,i);d.logger.info(`[SiteState] cleared ${m} page cache entries for project ${a}, routes:`,e)}};addConnection=e=>{if(this.conns.has(e))return;this.cancelRelease(),e.binaryType="arraybuffer",this.conns.set(e,new Set),e.on("message",n=>this.messageListener(e,new Uint8Array(n)));let s=!0;const a=setInterval(()=>{if(!s)this.conns.has(e)&&this.closeConn(e),clearInterval(a);else if(this.conns.has(e)){s=!1;try{e.ping()}catch{this.closeConn(e),clearInterval(a)}}},kt);e.on("close",()=>{this.closeConn(e),clearInterval(a)}),e.on("pong",()=>{s=!0});{const n=v.createEncoder();v.writeVarUint(n,H),le.writeSyncStep1(n,this),this.send(e,v.toUint8Array(n));const o=this.awareness.getStates();if(o.size>0){const i=v.createEncoder();v.writeVarUint(i,de),v.writeVarUint8Array(i,z.encodeAwarenessUpdate(this.awareness,Array.from(o.keys()))),this.send(e,v.toUint8Array(i))}}};messageListener=(e,s)=>{try{const a=v.createEncoder(),n=pe.createDecoder(s),o=pe.readVarUint(n);switch(o){case H:v.writeVarUint(a,H),le.readSyncMessage(n,a,this,null),v.length(a)>1&&(this.ensureDataStructure(),this.send(e,v.toUint8Array(a)));break;case de:{z.applyAwarenessUpdate(this.awareness,pe.readVarUint8Array(n),e);break}default:d.logger.warn(`Unsupported messageType ${o}`)}}catch(a){d.logger.error(a)}this.save()};static async pageUrlMap(e,s){let a=[];s?a=[s]:a=await this.getProjectIds();let n={};if(e==="production"&&a?.length){const o=new Map(a?.map(i=>[i,!0])||[]);for(const i of a){const c=O.pageUrlMapCache.get(i);c&&(n={...n,...c},o.delete(i))}a=Array.from(o.keys())}if(a?.length){const o=await L.findAll({where:{id:{[C.Op.in]:a}}});await Promise.all(o?.map(async i=>{const c=i.id,p=i.slug||c,m={},k=e==="production"&&i?.productionState?i.productionState:await O.getStateByProjectId(i.id,e),T=gt.default(E.default.env.languages?.map(u=>u.code)||[],k.supportedLocales?.map(u=>u.locale)||[]),w=(u,l)=>{p&&(m[Y.joinURL("/",p,u)]={...l,shouldRedirect:!0,mainPage:!0}),m[Y.joinURL("/",c,u)]={...l,shouldRedirect:!0,mainPage:!0};for(const y of T){const j={...l,locale:y};m[Y.joinURL("/",y,c,u)]=j,p&&(m[Y.joinURL("/",y,p,u)]=j)}};if(e==="draft")for(const u of k.routeIds||[]){const l=k?.routes?.[u];if(!l)continue;if(l.params&&l.params.length>0){const h=Q.generateParamCombinations({basePath:l.path,params:l.params,routeId:l.id,paramsOptions:l.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const f of h){const S=f.path,A={projectId:c,projectSlug:p,pageSlug:S,pageId:l.displayTemplateId||"",routeId:u,defaultLocale:T?.[0],locales:T,publishedAt:k.config.publishedAt,isPublic:l.isPublic&&f?.routeMetaData?.isPublic};w(S,A)}}const y=l.path,j={projectId:c,projectSlug:p,pageSlug:y,pageId:l.displayTemplateId||"",routeId:u,defaultLocale:T?.[0],locales:T,publishedAt:k.config.publishedAt,isPublic:l.isPublic};w(y,j)}for(const u of k.pageIds){const l=k.pages[u];if(!l||e==="production"&&!l.isPublic)continue;const y=l.slug,j=i.slug||c,h={projectId:c,projectSlug:j,pageSlug:y,pageId:u,defaultLocale:T?.[0],locales:T,publishedAt:k.config.publishedAt,isPublic:l.isPublic,templateConfig:l.templateConfig};w(y,h)}e==="production"&&O.pageUrlMapCache.set(c,m),n={...n,...m}}))}return n}getDocumentSize(){return $.encodeStateAsUpdate(this).byteLength}static getInstancesSizeInfo(){const e=[];for(const[s,a]of Object.entries(O.sharedInstances)){const n=a.getDocumentSize();e.push({projectId:s,sizeInBytes:n,sizeInMB:`${(n/(1024*1024)).toFixed(2)} MB`,activeConnections:a.conns.size})}return e}static startPeriodicCheck(){this.periodicCheckTimer||(this.periodicCheckTimer=setInterval(()=>{this.performPeriodicCheck()},this.PERIODIC_CHECK_INTERVAL),d.logger.info(`[SiteState] periodic check started, interval: ${this.PERIODIC_CHECK_INTERVAL/(60*60*1e3)} hours`))}static stopPeriodicCheck(){this.periodicCheckTimer&&(clearInterval(this.periodicCheckTimer),this.periodicCheckTimer=void 0,d.logger.info("[SiteState] periodic check stopped"))}static performPeriodicCheck(){const e=Object.keys(O.sharedInstances).length,s=[],a=[];for(const[n,o]of Object.entries(O.sharedInstances))o.conns.size===0?s.push({projectId:n,instance:o}):a.push({projectId:n,connections:o.conns.size});if(d.logger.info(`[SiteState] periodic check summary: total instances: ${e}, with connections: ${a.length}, without connections: ${s.length}`),s.length>0){d.logger.info(`[SiteState] releasing ${s.length} instances without connections:`,s.map(o=>o.projectId));let n=0;for(const{projectId:o,instance:i}of s)try{d.logger.info(`[SiteState] releasing instance due to periodic check: ${o}`),i.destroy(),n++}catch(c){d.logger.error(`[SiteState] failed to release instance ${o} during periodic check:`,c)}d.logger.info(`[SiteState] periodic check completed: ${n}/${s.length} instances released successfully`)}else e>0?d.logger.debug("[SiteState] periodic check: all instances have active connections"):d.logger.debug("[SiteState] periodic check: no instances exist")}}async function $t(t,e,s){if(!t||!I.existsSync(t)||!I.lstatSync(t).isFile())return null;let a=s[t];return a||(a=(async()=>{try{return(await Tt({filePath:t,fileName:e}))?.data?.filename}catch(n){return d.logger.error(`Failed to upload asset ${t}:`,n),null}})(),s[t]=a),a}const $e=async(t,e)=>{const s=g.basename(t),a=await Ie.call({name:Pe,path:Y.joinURL("/uploads",s),responseType:"stream",method:"GET"});if(a.status>=200&&a.status<400){const n=I.createWriteStream(e);await lt.pipeline(a.data,n)}else throw new Error(`download asset failed ${a.status}`)},Ue=async(t,e)=>{await Promise.all(t.map(async s=>{try{await $e(s,g.join(e,g.basename(s)))}catch(a){d.logger.error(`Failed to export assets: ${s}, ${a}`)}}))};function Me(t){return Oe.test(t)?[t]:J.test(t)?(ke.lastIndex=0,Array.from(t.matchAll(ke)).map(s=>s[1]).filter(s=>!!s)):[]}async function W(t,e,s){const{getFilename:a,exportAssets:n}=s,o=g.join(e,a(t));if(I.mkdirSync(g.dirname(o),{recursive:!0}),I.writeFileSync(o,x.stringify(t)),n){const c=ee(t,p=>typeof p=="string"&&(Oe.test(p)||J.test(p))).map(p=>{const m=Ee.default(t,p);return Me(m)}).flat().filter(Boolean);await Ue(c,g.dirname(o))}}const ye=new be.LRUCache({max:100,ttl:1*60*1e3});async function ve(t,e,s){const a=ee(t,c=>typeof c=="string"&&(Oe.test(c)||J.test(c))),n=mt.default(2),o=a.map(c=>n(async()=>{try{const p=Ee.default(t,c),m=Me(p);for(const k of m){const T=g.basename(k),w=s.getFilePath(k,c),u=w?`${w}:${T}`:T,l=ye.get(u);if(l){J.test(p)||De.default(t,c,l);return}const y=await $t(w,T,e);y&&(J.test(p)||De.default(t,c,y),ye.set(u,y))}}catch(p){d.logger.error(`Failed to process upload for path ${c.join(".")}:`,p.message||p.reason)}})),i=await Promise.allSettled(o);s.onFinish?.(i)}async function Ne(t,{exportAssets:e,pageIds:s="all",componentIds:a="all",rawConfig:n,includeResources:o=!1,routeIds:i="all"}={}){const c=s==="all"?t.pageIds:s,p=Xe.getComponentDependencies({state:t,pageIds:c,componentIds:a==="all"?Object.keys(t.components):a}),m=i==="all"?t.routeIds:i,k=r=>({id:r.id,name:r.name,isTemplateSection:r.isTemplateSection??!1,templateDescription:r.templateDescription,llmConfig:r.llmConfig,component:r.component,config:r.config,visibility:r.visibility,sections:r?.sectionIds?R(r?.sectionIds?.map(b=>{const D=r.sections?.[b];return D&&k(D)})):void 0}),T=(r,b)=>({id:r.id,createdAt:r.createdAt,updatedAt:r.updatedAt,publishedAt:r.publishedAt,isPublic:r.isPublic??!0,templateConfig:r.templateConfig,meta:r.locales?.[b]??{},sections:R(r.sectionIds.map(D=>{const N=r.sections[D];return N&&k(N)})),dataSource:Object.fromEntries(Object.entries(r.dataSource||{}).map(([D,N])=>[D,N?.[b]??{}]))}),w=r=>({id:r.id,createdAt:r.createdAt,updatedAt:r.updatedAt,publishedAt:r.publishedAt,path:r.path,handler:r.handler,isPublic:r.isPublic??!0,params:r.params??[],enabledGenerate:r.enabledGenerate??!1,displayTemplateId:r.displayTemplateId,dataSource:r.dataSource}),u=R(m.map(r=>{const b=t.routes[r];return b&&w(b)})),l=R(t.supportedLocales.map(r=>r.locale).flatMap(r=>c.map(b=>{const D=t.pages[b];return D&&{locale:r,slug:D.slug,page:T(D,r)}}))),y=Le(),j=g.join(y,"pages");I.mkdirSync(j,{recursive:!0});const h=g.join(y,"components");I.mkdirSync(h,{recursive:!0});const f=g.join(y,"routes");I.mkdirSync(f,{recursive:!0});for(const{locale:r,slug:b,page:D}of l)await W(D,j,{getFilename:()=>`${te(b)||"index"}.${r}.yml`,exportAssets:e});for(const r of u)await W(r,f,{getFilename:()=>`${te(r.path)||"index"}.yml`,exportAssets:e});for(const r of p){const b=t.components[r]?.data;b&&await W(b,h,{getFilename:D=>`${D.name||"unnamed"}.${D.id}.yml`,exportAssets:e})}const S=g.join(y,".blocklet/pages/pages.config.yml");I.mkdirSync(g.dirname(S),{recursive:!0});const A={pages:R(c.map(r=>{const b=t.pages[r];return b&&{id:r,slug:b.slug}})),routes:R(m.map(r=>{const b=t.routes[r];return b&&{id:r,path:b.path}})),components:R(p.map(r=>{const b=t.components[r]?.data;return b&&{id:r,name:b.name}})),...o?{resources:{components:R(Object.keys(t.resources?.components||{}).filter(r=>p.includes(r)).map(r=>({id:r,name:t.resources?.components?.[r]?.component?.name})))}}:{},supportedLocales:t.supportedLocales,config:t.config};I.writeFileSync(S,x.stringify(A));const P=g.join(y,"config.source.json");if(n&&I.writeFileSync(P,JSON.stringify(n)),o){const r=g.join(y,"resources"),b=g.join(r,"components");I.mkdirSync(b,{recursive:!0});for(const V of Object.keys(t?.resources?.components??{}).filter(_=>p.includes(_))){const _=t.resources?.components?.[V]?.component;_&&await W(_,b,{getFilename:G=>`${G.name||"unnamed"}.${G.id}.yml`,exportAssets:e})}const D=g.join(y,"chunks");I.mkdirSync(D,{recursive:!0});const N=Ut();for(const V of Object.keys(t?.resources?.components??{}).filter(_=>p.includes(_))){const _=t.resources?.components?.[V]?.component;if(_&&_.renderer?.type==="react-component"){const G=_.renderer?.chunks??[];if(G?.length>0)for(const ie of G){const je=g.join(D,ie),ce=N?.[ie];try{ce&&I.existsSync(ce)&&!I.existsSync(je)&&I.copyFileSync(ce,je)}catch(Ye){d.logger.error(`copy chunk ${ie} error`,Ye.message)}}}}}return y}async function Ce(t,{importAssets:e,includeResources:s}={}){if(!I.existsSync(t))return null;let a,n=!1;try{I.lstatSync(t).isDirectory()?a=t:/\.(tgz|gz|tar)$/.test(t)&&(n=!0,a=Le(),await pt.x({file:t,C:a}));const o=X.globSync("**/.blocklet/pages/pages.config.yml",{cwd:a,absolute:!0}).at(0),i=o&&g.join(g.dirname(o),"../../pages"),c=o&&g.join(g.dirname(o),"../../components"),p=o&&g.join(g.dirname(o),"../../routes");if(!o)return null;const m=x.parse(I.readFileSync(o).toString()),k=(h,f,S)=>{let A=g.join(h,`${f}${S?`.${S}`:""}.yml`);return(!I.existsSync(A)||!I.lstatSync(A).isFile())&&(A=g.join(h,f,`index${S?`.${S}`:""}.yml`),!I.existsSync(A)||!I.lstatSync(A))?null:x.parse(I.readFileSync(A).toString())},T=(h,f)=>{try{const S=X.globSync(`*.${f}.yml`,{cwd:h,absolute:!0})[0];return S?x.parse(I.readFileSync(S).toString()):null}catch(S){d.logger.error("parse component error",S)}return null},w=(h,f)=>{let S=g.join(h,`${f}.yml`);return(!I.existsSync(S)||!I.lstatSync(S).isFile())&&(S=g.join(h,f,"index.yml"),!I.existsSync(S)||!I.lstatSync(S))?null:x.parse(I.readFileSync(S).toString())},u=R(m.pages.map(({slug:h})=>{const f=R(m.supportedLocales.map(({locale:P})=>{const r=i?k(i,te(h),P):void 0;if(r)return{locale:P,page:r};const b=i?k(i,h,P):void 0;return b&&{locale:P,page:b}})),S=f[0]?.page;if(!S)return null;const A=S.sections.map(Qe.unzipSection);return{id:S.id||Te.nextId(),createdAt:S.createdAt,updatedAt:S.updatedAt,publishedAt:S.publishedAt,isPublic:S.isPublic??!0,templateConfig:S.templateConfig,slug:h,sections:Object.fromEntries(A.map(P=>[P.id,P])),sectionIds:A.map(P=>P.id),locales:Object.fromEntries(f.map(({locale:P,page:r})=>[P,r.meta])),dataSource:S.dataSource?Object.fromEntries([...new Set(f.flatMap(({page:P})=>Object.keys(P.dataSource??{})))].map(P=>[P,Object.fromEntries(f.map(({locale:r,page:b})=>{const D=b.dataSource?.[P];return[r,D||{}]}))])):Object.fromEntries([...new Set(f.flatMap(({page:P})=>P.sections.map(r=>r.id)))].map(P=>[P,Object.fromEntries(f.map(({locale:r,page:b})=>{const D=b.dataSource?.[P];if(D)return[r,D];const N=b.sections.find(V=>V.id===P);return[r,N?.properties||{}]}))]))}})),l=R(m?.routes?.map(({path:h})=>{const f=p?w(p,te(h)):void 0;return{...f,id:f?.id||Te.nextId(),createdAt:f?.createdAt??new Date().toISOString(),updatedAt:f?.updatedAt??new Date().toISOString(),publishedAt:new Date(0).toISOString(),path:f?.path??`/${f?.id}`,params:f?.params,handler:f?.handler??"Pages Kit",isPublic:f?.isPublic??!0,enabledGenerate:f?.enabledGenerate??!1,displayTemplateId:f?.displayTemplateId??void 0,dataSource:f?.dataSource??{}}})??[]),y=c?R(m.components?.map(({id:h})=>T(c,h))??[]):[];if(e){const h=(...f)=>{d.logger.info(`[${n?g.basename(t):g.basename(g.join(t,"../../../../"))}] importAssets:`,...f)};try{h("wait image-bin api ready"),await ht.default({resources:[`${Ie.getComponentWebEndpoint(d.IMAGE_BIN_NAME)}/api/sdk/uploads`],validateStatus:A=>A>=200&&A<=500}),h("image-bin api is ready");const f={},S={};h("start to upload assets"),await Promise.allSettled([ve(y,f,{getFilePath:A=>c&&g.join(c,A),onFinish:A=>{h(`upload ${A.length} component assets`)}}),ve(u,S,{getFilePath:(A,P)=>{const r=Ee.default(u,P.slice(0,1));return i&&g.join(i,g.dirname(r.slug),A)},onFinish:A=>{h(`upload ${A.length} page assets`)}})]),h("upload assets done"),ye.clear(),global.gc&&global.gc()}catch(f){h("Error during asset import:",f)}}const j={};if(s){const h=o&&g.join(g.dirname(o),"../../resources/components"),f=R(m.resources?.components?.map(({id:S})=>T(h,S))??[]);f.length>0&&(j.components=Object.fromEntries(f.map((S,A)=>[S.id,{index:A,component:S}])))}return{supportedLocales:m.supportedLocales,pageIds:u.map(h=>h.id),components:Object.fromEntries(y.map((h,f)=>[h.id,{index:f,data:h}])),pages:Object.fromEntries(u.map(h=>[h.id,h])),config:m.config||{},resources:j,routeIds:l.map(h=>h.id),routes:Object.fromEntries(l.map(h=>[h.id,h])),dataSourceIds:[],dataSources:{}}}finally{n&&a&&I.rmSync(a,{force:!0,recursive:!0})}}async function Se(t,e,{routes:s,mergeMode:a="byUpdateTime",deleteRoutes:n=!1,publishMode:o=void 0}={}){try{o&&d.clearPreloadComponentsCacheByMode(o)}catch(w){d.logger.error("clear preload page cache error",{error:w})}const{pages:i,pageIds:c,routeIds:p,routes:m,supportedLocales:k}=t;if(o==="production"){let w=s??[],u=null;for(const l of p??[]){const y=m?.[l];if(y?.params&&y?.params.length>0&&y?.paramsOptions&&y?.paramsOptions.length>0){const j=Q.generateParamCombinations({basePath:y.path,params:y.params,routeId:y.id,paramsOptions:y.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]}),h=Object.fromEntries(j.map(f=>[`${l}-${f.paramOptionIds.join("-")}`,f]));u={...u||{},...h},s||(w=[...w,...j.map(f=>`${l}-${f.paramOptionIds.join("-")}`)])}else s||w.push(l)}d.logger.info("routeIds to be published: ",w);for(const l of w){let y=l;if(y.includes("-")){const[f]=y.split("-");y=f}const j=m?.[y];if(!j){const f=e.pageIds.indexOf(y);f!==-1&&n&&(e.pageIds.splice(f,1),delete e.pages[y]);for(const S of e.pageIds)S.includes(`${y}-`)&&(e.pageIds.splice(e.pageIds.indexOf(S),1),delete e.pages[S]);d.logger.info("delete main route page",y);continue}if(l.includes("-")&&!u?.[l]){const f=e.pageIds.indexOf(l);f!==-1&&n&&(e.pageIds.splice(f,1),delete e.pages[l]),d.logger.info("delete page",l);continue}if(!j.displayTemplateId){d.logger.info("no display template",l);continue}const h=i[j.displayTemplateId];if(!h){d.logger.info("no template page",l);continue}if(e.pageIds.includes(l)){if(d.logger.info("has need update page",l),a==="replace")e.pages[l]=ue({page:h,route:j,state:t,routeId:l,routePathInfo:u?.[l]}),d.logger.info("replace page",l);else if(a==="byUpdateTime"){const f=e.pages[j.id];(!f||j.updatedAt&&j.updatedAt>f.updatedAt)&&(e.pages[l]=ue({page:h,route:j,state:t,routeId:l,routePathInfo:u?.[l]}),d.logger.info("replace page by update time",l))}}else e.pageIds.push(l),e.pages[l]=ue({page:h,route:j,state:t,routeId:l,routePathInfo:u?.[l]}),d.logger.info("add page",l)}if(n&&!s)for(const l of e.pageIds)w?.includes(l)||(delete e.pages[l],d.logger.info("delete page",l)),e.pageIds=[...e.pageIds].filter(y=>w?.includes(y))}else{for(const w of c){const u=i[w];if(u)if(e.pageIds.includes(u.id)){if(a==="replace")e.pages[u.id]=u;else if(a==="byUpdateTime"){const l=e.pages[u.id];(!l||u.updatedAt&&u.updatedAt>l.updatedAt)&&(e.pages[u.id]=u)}}else e.pageIds.push(u.id),e.pages[u.id]=u}for(const w of p){const u=m[w];if(u)if(e.routeIds.includes(u.id)){if(a==="replace")e.routes[u.id]=u;else if(a==="byUpdateTime"){const l=e.routes[u.id];(!l||u.updatedAt&&u.updatedAt>l.updatedAt)&&(e.routes[u.id]=u)}}else e.routeIds.push(u.id),e.routes[u.id]=u}}if(e.supportedLocales.splice(0,e.supportedLocales.length),e.supportedLocales.push(...ft.default(k)),n)for(const w of Object.keys(e.components))delete e.components[w];let T=JSON.parse(JSON.stringify(t.components));T=Object.fromEntries(await Promise.all(Object.entries(T).map(async([w,u])=>{const l=await Fe(u?.data);return[w,{...u,data:l}]}))),Object.assign(e.components,T),Object.assign(e.config,JSON.parse(JSON.stringify(t.config))),we.default(t.resources.components)||(e.resources.components=JSON.parse(JSON.stringify(t.resources.components||{})))}const Fe=d.memoizeWithFs(async t=>{if(!we.default(t?.properties))return t;if(t?.renderer?.type==="react-component"){const{script:e,PROPERTIES_SCHEMA:s}=t?.renderer||{};if(s||e&&e.includes("PROPERTIES_SCHEMA"))try{const a=await d.getExportSchemaValueFromCode(e??"","PROPERTIES_SCHEMA",t.id,s);a&&a.length>0&&t&&(t.properties={},a.forEach((n,o)=>{t?.properties&&(t.properties[n.id]={index:o,data:n})}))}catch(a){d.logger.error("getPropertiesFromCode error",{componentId:t.id,name:t.name},{error:a})}}return t},{subdir:"getPropertiesFromCode"});let se,K,ne,oe;const qe=()=>Ie.getResources({types:[{did:Pe,type:ge},{did:bt,type:ge}]}),Ut=()=>{const t=qe(),e={};return t.forEach(s=>{const a=X.globSync("**/.blocklet/pages/pages.config.yml",{cwd:s.path,absolute:!0}).at(0),n=a&&g.join(g.dirname(a),"../../chunks");if(n&&I.existsSync(n)){const o=I.readdirSync(n);for(const i of o)e[i]=g.join(n,i)}}),e};function xe(){return se=(async()=>{const t=qe();K=(await Promise.all(t.map(async s=>{const a=s.path?await Ce(s.path,{importAssets:!1}):void 0;return a?{blockletId:s.did,state:a,blockletTitle:s.title}:void 0}))).filter(s=>!!s),ne=K.reduce((s,a)=>Object.assign(s,Object.fromEntries(Object.values(a.state.pages).map(n=>n?[n?.id,{page:n,blockletId:a.blockletId}]:[]))),{});const e=K.reduce((s,a)=>Object.assign(s,Object.fromEntries(Object.values(a.state.components).map(n=>[n.data.id,{blockletId:a.blockletId,component:n.data}]))),{});oe=Object.fromEntries(await Promise.all(Object.entries(e).map(async([s,a])=>{const n=await Fe(a.component);return[s,{...a,component:n}]})))})(),se}function Be(t){const e=Re.default(async()=>{await xe().catch(s=>{d.logger.error("load resource states error",{error:s})}),await t?.({states:K,pages:ne,components:oe})},3e3,{leading:!1,trailing:!0});return e(),E.default.events.on(E.default.Events.componentAdded,e),E.default.events.on(E.default.Events.componentRemoved,e),E.default.events.on(E.default.Events.componentStarted,e),E.default.events.on(E.default.Events.componentStopped,e),E.default.events.on(E.default.Events.componentUpdated,e),E.default.events.on(me,e),()=>{E.default.events.off(E.default.Events.componentAdded,e),E.default.events.off(E.default.Events.componentRemoved,e),E.default.events.off(E.default.Events.componentStarted,e),E.default.events.off(E.default.Events.componentStopped,e),E.default.events.off(E.default.Events.componentUpdated,e),E.default.events.off(me,e)}}const Ve=Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"),Ge=Symbol.for("GLOBAL_ENV_UPDATE_LISTENER_KEY"),re=globalThis;re[Ve]?.();re[Ve]=Be(async({pages:t,components:e})=>{const s=await O.getProjectIds();d.logger.info(`start update resource states projects(${s.length})`,s),await Promise.race([new Promise(a=>{setTimeout(()=>{a({})},30*1e3)}),Promise.all(s.map(async a=>{ze({projectId:a,pages:t,components:e})}))]).catch(a=>{d.logger.error("update resource states failed:",a)})});re[Ge]?.();re[Ge]=()=>{const t=()=>{O.pageUrlMapCache.clear(),d.logger.info("[Cache CLEAR ALL] clear all page url map cache by env update")};return E.default.events.on(E.default.Events.envUpdate,t),()=>{E.default.events.off(E.default.Events.envUpdate,t)}};O.startPeriodicCheck();process.on("beforeExit",()=>{O.stopPeriodicCheck()});process.on("SIGINT",()=>{O.stopPeriodicCheck(),process.exit(0)});process.on("SIGTERM",()=>{O.stopPeriodicCheck(),process.exit(0)});async function ze({projectId:t,pages:e,components:s}){const a=O.sharedInstances[t];if(!a){d.logger.info(`projectId: ${t} not found in sharedInstances`);return}if(a.syncedStore.resources.pages=e,(await L.findByPk(t))?.useAllResources)a.syncedStore.resources.components=s;else{const i=(await Ae.findAll({where:{projectId:t}})).map(p=>p.componentId),c=Object.fromEntries(Object.entries(s||{}).filter(([p])=>i.includes(p)));a.syncedStore.resources.components=c}d.logger.info(`update [${t}] resource states:`,{pages:Object.keys(a.syncedStore.resources.pages||{}).length,components:Object.keys(a.syncedStore.resources.components||{}).length})}async function Mt(){d.logger.info("trigger reload all project resource"),E.default.events.emit(me)}async function Nt({ensureLoaded:t=!0}={}){return t&&(se??=xe(),await se),{states:K,pages:ne,components:oe}}exports.COMPONENT_DID=Pe;exports.PUBLISH_MODES=_t;exports.Project=L;exports.RESOURCE_TYPE=ge;exports.SITE_STATE_PATH=q;exports.STATE_MODES=Lt;exports.SiteState=O;exports.downloadAsset=$e;exports.downloadAssets=Ue;exports.fromPackage=Ce;exports.getDefaultState=_e;exports.getResourceStates=Nt;exports.initPackResourceStates=Be;exports.mergeState=Se;exports.toPackage=Ne;exports.triggerReloadAllProjectResource=Mt;