@blocklet/pages-kit-inner-components 0.6.86 → 0.6.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/chunks/site-state-pWDDyjH2.js +1 -0
- package/lib/cjs/resources.js +1 -1
- package/lib/cjs/site-state.js +1 -1
- package/lib/es/chunks/{site-state-B0mj1K8f.js → site-state-Ia5YbZtX.js} +28 -25
- package/lib/es/resources.js +1 -1
- package/lib/es/site-state.js +1 -1
- package/package.json +3 -3
- package/lib/cjs/chunks/site-state-2LMcqIzO.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const f=require("./components-DLLpFRy5.js"),q=require("@syncedstore/core"),Qe=require("yjs"),Ze=require("@blocklet/pages-kit/utils/data-source"),Q=require("@blocklet/pages-kit/utils/route"),et=require("lodash/cloneDeep"),tt=require("@blocklet/sdk/lib/config"),I=require("fs"),g=require("path"),Re=require("@blocklet/pages-kit/utils/common"),st=require("@blocklet/pages-kit/utils/page-model"),at=require("@blocklet/pages-kit/utils/property"),Ee=require("@blocklet/sdk/lib/component"),nt=require("@reactivedata/reactive"),Z=require("glob"),ot=require("lib0/decoding"),rt=require("lib0/encoding"),it=require("lodash/debounce"),ct=require("lodash/get"),lt=require("lodash/isEmpty"),ut=require("lodash/set"),pt=require("lodash/union"),be=require("lru-cache"),dt=require("p-limit"),T=require("sequelize"),ft=require("stream/promises"),gt=require("tar"),F=require("ufo"),mt=require("wait-on"),z=require("y-protocols/awareness"),ue=require("y-protocols/sync"),ht=require("yaml"),ve=require("./html-xfTPTsl5.js");require("sqlite3");require("@blocklet/pages-kit/types/state");const $=t=>t&&t.__esModule?t:{default:t};function ne(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 U=ne(Qe),we=$(et),w=$(tt),pe=ne(ot),v=ne(rt),Me=$(it),Pe=$(ct),Ae=$(lt),ke=$(ut),yt=$(pt),St=$(dt),It=$(mt),B=ne(ht),Et=T.DataTypes.sqlite.DATE.parse;T.DataTypes.sqlite.DATE.parse=(t,e)=>typeof t=="number"?new Date(t):Et(t,e);const M=new T.Sequelize({dialect:"sqlite",storage:f.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});M.query("pragma journal_mode = WAL;");M.query("pragma synchronous = normal;");M.query("pragma journal_size_limit = 33554432;");M.query("pragma cache_size = -2000;");M.query("pragma mmap_size = 33554432;");process.on("SIGINT",async()=>{await M.close(),process.exit(0)});process.on("SIGTERM",async()=>{await M.close(),process.exit(0)});async function bt(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 ge=null;ge&&clearInterval(ge);ge=setInterval(async()=>{f.logger.info("Start cleanupSqliteMemory"),await bt(M,f.databaseUrl),f.logger.info("End cleanupSqliteMemory")},60*1e3*10);const wt="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o",me="page",he="trigger-reload-project-resource",je=wt,Pt="z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM",At="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o";class Oe extends T.Model{}Oe.init({id:{type:T.DataTypes.UUID,allowNull:!1,primaryKey:!0,defaultValue:T.DataTypes.UUIDV4},projectId:{type:T.DataTypes.UUID,allowNull:!1},componentId:{type:T.DataTypes.STRING,allowNull:!1}},{sequelize:M,tableName:"ProjectComponents",timestamps:!1});const jt="SLUG_INVALID",Y=t=>({error:"slugInvalid",code:jt,field:"slug",message:t}),Ot={error:"slugRequired",code:"SLUG_REQUIRED",field:"slug",message:()=>"Project slug is required"},Tt={error:"slugAlreadyExists",code:"SLUG_EXISTS",field:"slug",message:t=>`Project slug "${t}" already exists`},Ct=[/\.\./,/<[^>]*>/,/%[0-9a-f]{2}/i,/[<>'"%;{}()\\]/,/\x00/,/\n|\r|\t|\v|\f/,/[^a-zA-Z0-9-_@/\\:]/],Le=t=>{if(!t)return"";if(t==="/")return"/";const e=F.withoutTrailingSlash(t);return F.withLeadingSlash(e)||"/"},Dt=t=>t.did===At;class L extends T.Model{static async getProjectByIdOrSlug(e,s){return e?L.findOne({where:{[T.Op.or]:[{id:e},{slug:e}],...s?.createdBy?{createdBy:s.createdBy}:{}},paranoid:!1}):null}static async validateProjectSlug({slug:e,projectId:s}){if(e==null)return null;if(e==="")return Ot;const a=Le(e);if(e!=="/"&&e.endsWith("/"))return Y(r=>`Project slug "${r}" cannot end with /`);if(/\/{2,}/.test(e))return Y(r=>`Project slug "${r}" cannot contain consecutive /`);if(/\s/.test(e))return Y(r=>`Project slug "${r}" cannot contain whitespace`);if(Ct.some(r=>r.test(e)))return Y(r=>`Project slug "${r}" contains invalid characters`);if(w.default.components?.filter(r=>r.mountPoint&&!Dt(r)).some(r=>Le(r.mountPoint)===a))return Y(r=>`Project slug "${r}" conflicts with existing blocklet`);const o=await L.findOne({where:{slug:`${e}`}});return o&&o?.id!==s?Tt:null}}L.init({id:{type:T.DataTypes.UUID,defaultValue:T.DataTypes.UUIDV4,primaryKey:!0},name:{type:T.DataTypes.STRING,allowNull:!1},description:T.DataTypes.TEXT,createdAt:T.DataTypes.DATE,updatedAt:T.DataTypes.DATE,createdBy:{type:T.DataTypes.STRING,allowNull:!1},updatedBy:{type:T.DataTypes.STRING,allowNull:!1},slug:T.DataTypes.STRING,icon:T.DataTypes.STRING,pinnedAt:T.DataTypes.DATE,useAllResources:T.DataTypes.BOOLEAN,npmSecret:T.DataTypes.STRING,relatedBlocklets:{type:T.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 f.logger.error("Failed to parse relatedBlocklets",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("relatedBlocklets",t?JSON.stringify(t):"{}")}catch(e){f.logger.error("Failed to set relatedBlocklets",{error:e,value:t}),this.setDataValue("relatedBlocklets","{}")}}},productionState:{type:T.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 f.logger.error("Failed to parse productionState",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("productionState",t?JSON.stringify(t):"{}")}catch(e){f.logger.error("Failed to set productionState",{error:e,value:t}),this.setDataValue("productionState","{}")}}}},{sequelize:M,paranoid:!0});L.hasMany(Oe,{foreignKey:"projectId",as:"components"});function ee(t){t.observeDeep(e=>{e.some(s=>s.changes.keys.has("updatedAt")||s.changes.keys.has("publishedAt"))||t.set("updatedAt",new Date().toISOString())})}function $e(){return I.mkdtempSync(g.join(w.default.env.dataDir,"tmp-"))}function te(t,e,s=[]){return Array.isArray(t)?t.flatMap((a,n)=>te(a,e,[...s,n])):typeof t=="object"?t===null?[]:Object.entries(t).flatMap(([a,n])=>te(n,e,[...s,a])):e(t)?[s]:[]}function k(t){return t.filter(e=>e!=null)}function Rt(t){t.pages&&Object.keys(t.pages).forEach(s=>{const a=q.getYjsValue(t.pages[s]);a&&a instanceof U.Map&&ee(a)});const e=q.getYjsValue(t.pages);e&&e instanceof U.Map&&e.observe(s=>{s.changes.keys.forEach((a,n)=>{if(a.action==="add"){const o=q.getYjsValue(t.pages[n]);o&&o instanceof U.Map&&ee(o)}})})}function vt(t){t.routes&&Object.keys(t.routes).forEach(s=>{const a=q.getYjsValue(t.routes?.[s]);a&&a instanceof U.Map&&ee(a)});const e=q.getYjsValue(t.routes);e&&e instanceof U.Map&&e.observe(s=>{s.changes.keys.forEach((a,n)=>{if(a.action==="add"){const o=q.getYjsValue(t.routes?.[n]);o&&o instanceof U.Map&&ee(o)}})})}function kt(t,e){for(const s of e||Object.keys(t.routes||{})){let a=s,n=[];if(s.includes("-")){const[o,...r]=s.split("-");a=o,n=r||[]}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 r=Q.getRouteMetaDataByOptionIds(n,o);r&&(r.publishedAt=new Date().toISOString())}if(!e){const r=Q.generateParamCombinations({basePath:o.path,params:o.params,routeId:o.id,paramsOptions:o.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const l of r)l.routeMetaData??={},l.routeMetaData.publishedAt=new Date().toISOString()}}}}function de({page:t,route:e,state:s,routeId:a,routePathInfo:n}){f.logger.info(`Executing datasource data assembly, routeId: ${a}, routePathInfo: ${JSON.stringify(n)}`);const o={...we.default(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 r of s.supportedLocales){if(e.dataSource){let l=e.id;n&&(l=n.paramOptionIds.join("-"));const u=e.dataSource.pathDataMappings?.[l]?.dataCache?.[r.locale]??e.dataSource.pathDataMappings?.[l]?.dataCache?.[s.config.defaultLocale||"en"];if(!u)continue;Ze.setPageDataSource(o,s,r.locale,u)}n&&n.routeMetaData&&(n.routeMetaData.publishedAt=new Date().toISOString())}return o}["true","1","yes","y"].includes(process.env.USE_FS_CACHE_HTML??"");const Lt=60*60*1e3,H=new be.LRUCache({max:100,ttl:Lt,ttlResolution:10*1e3,allowStale:!0});function _t(t,e=[]){let s=0;const a=Array.from(H.keys()),n=t.map(o=>F.withoutTrailingSlash(o));for(const o of a)for(const r of n){if(ve.matchCacheKey(o,{currentPath:r})){H.delete(o),s++,f.logger.info(`[Cache CLEAR] key: ${o}`);break}for(const l of e)if(ve.matchCacheKey(o,{currentPath:`/${l}${r}`})){H.delete(o),s++,f.logger.info(`[Cache CLEAR] key: ${o}`);break}}return f.logger.info(`[Cache CLEAR] cleared ${s} entries for paths:`,n),s}function Ut(){const t=H.size;return H.clear(),f.logger.info(`[Cache CLEAR ALL] cleared ${t} entries`),t}w.default.events.on(w.default.Events.envUpdate,Ut);const{uploadToMediaKit:Mt}=require("@blocklet/uploader-server"),Te=/^\w+(\w|-|\.)+\w+\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm)$/,K=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/i,_e=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/gi,$t=1e4,Nt=3e4,W=0,fe=1,Ft=0,qt=1,ye=w.default,x=g.join(process.env.BLOCKLET_DATA_DIR,"site-state"),xt=["production","draft"],Bt=["production"];function se(t){return t?.replace(/\//g,"|")||""}function Ne(){const t=ye.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 U.Doc{constructor(e){super(),this.options=e,I.existsSync(this.draftYjsFilePath)&&U.applyUpdate(this,I.readFileSync(this.draftYjsFilePath)),this.syncedStore=nt.reactive(q.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(x,e),a=g.join(x,`@del-${e}`);I.renameSync(s,a)}catch(s){f.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 Z.globSync("*/",{cwd:x,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(x,e)}),O.sharedInstances[e]=s,s)}static async getProductionState(e){const s=await L.findByPk(e,{attributes:["productionState"]});if(Ae.default(s?.productionState)){const a=g.join(x,e,"production"),n=await Ce(a,{includeResources:!0})??Ne();if(!n?.config?.defaultLocale){n.config??={};const o=ye.env.languages?.map(r=>({locale:r.code,name:r.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(){Rt(this.syncedStore),vt(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 Be(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);const r=we.default(s);await L.update({productionState:r},{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 u=this.conns.get(n);u&&(e.forEach(S=>{u.add(S)}),a.forEach(S=>{u.delete(S)}))}const r=v.createEncoder();v.writeVarUint(r,fe),v.writeVarUint8Array(r,z.encodeAwarenessUpdate(this.awareness,o));const l=v.toUint8Array(r);this.conns.forEach((u,S)=>this.send(S,l))};updateHandler=e=>{const s=v.createEncoder();v.writeVarUint(s,W),ue.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:r}=this.syncedStore;{const l=new Set(Object.keys(s));let u=0;for(;u<a.length;){const S=a[u];l.has(S)?(l.delete(S),u++):a.splice(u,1)}}{const l=new Set(Object.keys(o));let u=0;for(;u<r.length;){const S=r[u];l.has(S)?(l.delete(S),u++):r.splice(u,1)}}e.splice(0,e.length),e.push(...ye.env.languages.map(l=>({locale:l.code,name:l.name}))),n.defaultLocale=e[0]?.locale;{let l=0;const u=new Set;for(;l<e.length;){const{locale:S}=e[l];u.has(S)?e.splice(l,1):(l++,u.add(S))}}};send=(e,s)=>{e.readyState!==Ft&&e.readyState!==qt&&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(()=>{f.logger.info(`[SiteState] releasing instance due to no active connections: ${e}`),this.conns.size===0&&(this.releaseTimer=void 0,this.destroy())},O.RELEASE_DELAY),f.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);f.logger.info(`[SiteState] cancelled scheduled release for project ${e}`)}}autoSave=Me.default(()=>{I.mkdirSync(g.dirname(this.draftYjsFilePath),{recursive:!0}),I.writeFileSync(this.draftYjsFilePath,U.encodeStateAsUpdate(this))},$t);save=({flush:e=!1}={})=>{this.autoSave(),e&&this.autoSave.flush()};publish=async({mode:e,routes:s})=>{const a=g.basename(this.options.path);await We(a);const n=await this.getState("draft"),o=await this.getState("production");await Ie(n,o,{routes:s,mergeMode:"replace",deleteRoutes:!0,publishMode:e}),o.config.publishedAt=new Date().getTime(),kt(this.syncedStore,s),await this.setState(e,o),await this.clearPageCacheForRoutes(s,o)};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((r,l)=>{this.transact(async()=>{try{const u=await Ie(e,s);r(u)}catch(u){l(u)}})})};clearPageCacheForRoutes=async(e,s)=>{const a=g.basename(this.options.path),o=(await L.findByPk(a))?.slug||a;let r=e;(!r||r.length===0)&&(r=s.pageIds??[]),f.logger.info(`[SiteState] clearing page cache for project ${a}, routes:`,r||[]);const l=s.supportedLocales.map(P=>P.locale),u=[],S=r.filter(P=>s.pageIds?.includes(P));for(const P of S){const b=s.pages[P].slug;o&&o!==a&&(o==="/"?u.push(b):u.push(`/${o}${b}`)),u.push(`/${a}${b}`)}if(u.length>0)try{const P=_t(u,l);f.logger.info(`[SiteState] cleared ${P} page cache entries for project ${a}, routes:`,r)}catch{}};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)}}},Nt);e.on("close",()=>{this.closeConn(e),clearInterval(a)}),e.on("pong",()=>{s=!0});{const n=v.createEncoder();v.writeVarUint(n,W),ue.writeSyncStep1(n,this),this.send(e,v.toUint8Array(n));const o=this.awareness.getStates();if(o.size>0){const r=v.createEncoder();v.writeVarUint(r,fe),v.writeVarUint8Array(r,z.encodeAwarenessUpdate(this.awareness,Array.from(o.keys()))),this.send(e,v.toUint8Array(r))}}};messageListener=(e,s)=>{try{const a=v.createEncoder(),n=pe.createDecoder(s),o=pe.readVarUint(n);switch(o){case W:v.writeVarUint(a,W),ue.readSyncMessage(n,a,this,null),v.length(a)>1&&(this.ensureDataStructure(),this.send(e,v.toUint8Array(a)));break;case fe:{z.applyAwarenessUpdate(this.awareness,pe.readVarUint8Array(n),e);break}default:f.logger.warn(`Unsupported messageType ${o}`)}}catch(a){f.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(r=>[r,!0])||[]);for(const r of a){const l=O.pageUrlMapCache.get(r);l&&(n={...n,...l},o.delete(r))}a=Array.from(o.keys())}if(a?.length){const o=await L.findAll({where:{id:{[T.Op.in]:a}}});await Promise.all(o?.map(async r=>{const l=r.id,u=r.slug||l,S={},P=e==="production"&&r?.productionState?r.productionState:await O.getStateByProjectId(r.id,e),R=yt.default(w.default.env.languages?.map(p=>p.code)||[],P.supportedLocales?.map(p=>p.locale)||[]),b=(p,c)=>{u&&(S[F.joinURL("/",u,p)]={...c,shouldRedirect:!0,mainPage:!0}),S[F.joinURL("/",l,p)]={...c,shouldRedirect:!0,mainPage:!0};for(const h of R){const C={...c,locale:h};S[F.joinURL("/",h,l,p)]=C,u&&(S[F.joinURL("/",h,u,p)]=C)}};if(e==="draft")for(const p of P.routeIds||[]){const c=P?.routes?.[p];if(!c)continue;if(c.params&&c.params.length>0){const m=Q.generateParamCombinations({basePath:c.path,params:c.params,routeId:c.id,paramsOptions:c.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const d of m){const y=d.path,A={projectId:l,projectSlug:u,pageSlug:y,pageId:c.displayTemplateId||"",routeId:p,defaultLocale:R?.[0],locales:R,publishedAt:P.config.publishedAt,isPublic:c.isPublic&&d?.routeMetaData?.isPublic};b(y,A)}}const h=c.path,C={projectId:l,projectSlug:u,pageSlug:h,pageId:c.displayTemplateId||"",routeId:p,defaultLocale:R?.[0],locales:R,publishedAt:P.config.publishedAt,isPublic:c.isPublic};b(h,C)}for(const p of P.pageIds||[]){const c=P.pages[p];if(!c||e==="production"&&!c.isPublic)continue;const h=c.slug,C=r.slug||l,m={projectId:l,projectSlug:C,pageSlug:h,pageId:p,defaultLocale:R?.[0],locales:R,publishedAt:P.config.publishedAt,isPublic:c.isPublic,templateConfig:c.templateConfig};b(h,m)}e==="production"&&O.pageUrlMapCache.set(l,S),n={...n,...S}}))}return n}getDocumentSize(){return U.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),f.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,f.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(f.logger.info(`[SiteState] periodic check summary: total instances: ${e}, with connections: ${a.length}, without connections: ${s.length}`),s.length>0){f.logger.info(`[SiteState] releasing ${s.length} instances without connections:`,s.map(o=>o.projectId));let n=0;for(const{projectId:o,instance:r}of s)try{f.logger.info(`[SiteState] releasing instance due to periodic check: ${o}`),r.destroy(),n++}catch(l){f.logger.error(`[SiteState] failed to release instance ${o} during periodic check:`,l)}f.logger.info(`[SiteState] periodic check completed: ${n}/${s.length} instances released successfully`)}else e>0?f.logger.debug("[SiteState] periodic check: all instances have active connections"):f.logger.debug("[SiteState] periodic check: no instances exist")}}async function Gt(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 Mt({filePath:t,fileName:e}))?.data?.filename}catch(n){return f.logger.error(`Failed to upload asset ${t}:`,n),null}})(),s[t]=a),a}const Fe=async(t,e)=>{const s=g.basename(t),a=await Ee.call({name:je,path:F.joinURL("/uploads",s),responseType:"stream",method:"GET"});if(a.status>=200&&a.status<400){const n=I.createWriteStream(e);await ft.pipeline(a.data,n)}else throw new Error(`download asset failed ${a.status}`)},qe=async(t,e)=>{await Promise.all(t.map(async s=>{try{await Fe(s,g.join(e,g.basename(s)))}catch(a){f.logger.error(`Failed to export assets: ${s}, ${a}`)}}))};function xe(t){return Te.test(t)?[t]:K.test(t)?(_e.lastIndex=0,Array.from(t.matchAll(_e)).map(s=>s[1]).filter(s=>!!s)):[]}async function X(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,B.stringify(t)),n){const l=te(t,u=>typeof u=="string"&&(Te.test(u)||K.test(u))).map(u=>{const S=Pe.default(t,u);return xe(S)}).flat().filter(Boolean);await qe(l,g.dirname(o))}}const Se=new be.LRUCache({max:100,ttl:1*60*1e3});async function Ue(t,e,s){const a=te(t,l=>typeof l=="string"&&(Te.test(l)||K.test(l))),n=St.default(2),o=a.map(l=>n(async()=>{try{const u=Pe.default(t,l),S=xe(u);for(const P of S){const R=g.basename(P),b=s.getFilePath(P,l),p=b?`${b}:${R}`:R,c=Se.get(p);if(c){K.test(u)||ke.default(t,l,c);return}const h=await Gt(b,R,e);h&&(K.test(u)||ke.default(t,l,h),Se.set(p,h))}}catch(u){f.logger.error(`Failed to process upload for path ${l.join(".")}:`,u.message||u.reason)}})),r=await Promise.allSettled(o);s.onFinish?.(r)}async function Be(t,{exportAssets:e,pageIds:s="all",componentIds:a="all",rawConfig:n,includeResources:o=!1,routeIds:r="all"}={}){const l=s==="all"?t.pageIds:s,u=at.getComponentDependencies({state:t,pageIds:l,componentIds:a==="all"?Object.keys(t.components):a});Object.entries(t.components).forEach(([i,E])=>{E.data?.renderer?.type==="component-template"&&u.push(i)});const S=r==="all"?t.routeIds:r,P=i=>({id:i.id,name:i.name,isTemplateSection:i.isTemplateSection??!1,templateDescription:i.templateDescription,component:i.component,config:i.config,visibility:i.visibility,sections:i?.sectionIds?k(i?.sectionIds?.map(E=>{const D=i.sections?.[E];return D&&P(D)})):void 0}),R=(i,E)=>({id:i.id,createdAt:i.createdAt,updatedAt:i.updatedAt,publishedAt:i.publishedAt,isPublic:i.isPublic??!0,templateConfig:i.templateConfig,meta:i.locales?.[E]??{},sections:k(i.sectionIds.map(D=>{const N=i.sections[D];return N&&P(N)})),dataSource:Object.fromEntries(Object.entries(i.dataSource||{}).map(([D,N])=>[D,N?.[E]??{}]))}),b=i=>({id:i.id,createdAt:i.createdAt,updatedAt:i.updatedAt,publishedAt:i.publishedAt,path:i.path,handler:i.handler,isPublic:i.isPublic??!0,params:i.params??[],enabledGenerate:i.enabledGenerate??!1,displayTemplateId:i.displayTemplateId,dataSource:i.dataSource}),p=k(S.map(i=>{const E=t.routes[i];return E&&b(E)})),c=k(t.supportedLocales.map(i=>i.locale).flatMap(i=>l.map(E=>{const D=t.pages[E];return D&&{locale:i,slug:D.slug,page:R(D,i)}}))),h=$e(),C=g.join(h,"pages");I.mkdirSync(C,{recursive:!0});const m=g.join(h,"components");I.mkdirSync(m,{recursive:!0});const d=g.join(h,"routes");I.mkdirSync(d,{recursive:!0});for(const{locale:i,slug:E,page:D}of c)await X(D,C,{getFilename:()=>`${se(E)||"index"}.${i}.yml`,exportAssets:e});for(const i of p)await X(i,d,{getFilename:()=>`${se(i.path)||"index"}.yml`,exportAssets:e});for(const i of u){const E=t.components[i]?.data;E&&await X(E,m,{getFilename:D=>`${D.name||"unnamed"}.${D.id}.yml`,exportAssets:e})}const y=g.join(h,".blocklet/pages/pages.config.yml");I.mkdirSync(g.dirname(y),{recursive:!0});const A={pages:k(l.map(i=>{const E=t.pages[i];return E&&{id:i,slug:E.slug}})),routes:k(S.map(i=>{const E=t.routes[i];return E&&{id:i,path:E.path}})),components:k(u.map(i=>{const E=t.components[i]?.data;return E&&{id:i,name:E.name}})),...o?{resources:{components:k(Object.keys(t.resources?.components||{}).filter(i=>u.includes(i)).map(i=>({id:i,name:t.resources?.components?.[i]?.component?.name})))}}:{},supportedLocales:t.supportedLocales,config:t.config};I.writeFileSync(y,B.stringify(A));const j=g.join(h,"config.source.json");if(n&&I.writeFileSync(j,JSON.stringify(n)),o){const i=g.join(h,"resources"),E=g.join(i,"components");I.mkdirSync(E,{recursive:!0});for(const G of Object.keys(t?.resources?.components??{}).filter(_=>u.includes(_))){const _=t.resources?.components?.[G]?.component;_&&await X(_,E,{getFilename:V=>`${V.name||"unnamed"}.${V.id}.yml`,exportAssets:e})}const D=g.join(h,"chunks");I.mkdirSync(D,{recursive:!0});const N=Vt();for(const G of Object.keys(t?.resources?.components??{}).filter(_=>u.includes(_))){const _=t.resources?.components?.[G]?.component;if(_&&_.renderer?.type==="react-component"){const V=_.renderer?.chunks??[];if(V?.length>0)for(const ce of V){const De=g.join(D,ce),le=N?.[ce];try{le&&I.existsSync(le)&&!I.existsSync(De)&&I.copyFileSync(le,De)}catch(Xe){f.logger.error(`copy chunk ${ce} error`,Xe.message)}}}}}return h}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=$e(),await gt.x({file:t,C:a}));const o=Z.globSync("**/.blocklet/pages/pages.config.yml",{cwd:a,absolute:!0}).at(0),r=o&&g.join(g.dirname(o),"../../pages"),l=o&&g.join(g.dirname(o),"../../components"),u=o&&g.join(g.dirname(o),"../../routes");if(!o)return null;const S=B.parse(I.readFileSync(o).toString()),P=(m,d,y)=>{let A=g.join(m,`${d}${y?`.${y}`:""}.yml`);return(!I.existsSync(A)||!I.lstatSync(A).isFile())&&(A=g.join(m,d,`index${y?`.${y}`:""}.yml`),!I.existsSync(A)||!I.lstatSync(A))?null:B.parse(I.readFileSync(A).toString())},R=(m,d)=>{try{const y=Z.globSync(`*.${d}.yml`,{cwd:m,absolute:!0})[0];return y?B.parse(I.readFileSync(y).toString()):null}catch(y){f.logger.error("parse component error",y)}return null},b=(m,d)=>{let y=g.join(m,`${d}.yml`);return(!I.existsSync(y)||!I.lstatSync(y).isFile())&&(y=g.join(m,d,"index.yml"),!I.existsSync(y)||!I.lstatSync(y))?null:B.parse(I.readFileSync(y).toString())},p=k(S.pages.map(({slug:m})=>{const d=k(S.supportedLocales.map(({locale:j})=>{const i=r?P(r,se(m),j):void 0;if(i)return{locale:j,page:i};const E=r?P(r,m,j):void 0;return E&&{locale:j,page:E}})),y=d[0]?.page;if(!y)return null;const A=y.sections.map(st.unzipSection);return{id:y.id||Re.nextId(),createdAt:y.createdAt,updatedAt:y.updatedAt,publishedAt:y.publishedAt,isPublic:y.isPublic??!0,templateConfig:y.templateConfig,slug:m,sections:Object.fromEntries(A.map(j=>[j.id,j])),sectionIds:A.map(j=>j.id),locales:Object.fromEntries(d.map(({locale:j,page:i})=>[j,i.meta])),dataSource:y.dataSource?Object.fromEntries([...new Set(d.flatMap(({page:j})=>Object.keys(j.dataSource??{})))].map(j=>[j,Object.fromEntries(d.map(({locale:i,page:E})=>{const D=E.dataSource?.[j];return[i,D||{}]}))])):Object.fromEntries([...new Set(d.flatMap(({page:j})=>j.sections.map(i=>i.id)))].map(j=>[j,Object.fromEntries(d.map(({locale:i,page:E})=>{const D=E.dataSource?.[j];if(D)return[i,D];const N=E.sections.find(G=>G.id===j);return[i,N?.properties||{}]}))]))}})),c=k(S?.routes?.map(({path:m})=>{const d=u?b(u,se(m)):void 0;return{...d,id:d?.id||Re.nextId(),createdAt:d?.createdAt??new Date().toISOString(),updatedAt:d?.updatedAt??new Date().toISOString(),publishedAt:new Date(0).toISOString(),path:d?.path??`/${d?.id}`,params:d?.params,handler:d?.handler??"Pages Kit",isPublic:d?.isPublic??!0,enabledGenerate:d?.enabledGenerate??!1,displayTemplateId:d?.displayTemplateId??void 0,dataSource:d?.dataSource??{}}})??[]),h=l?k(S.components?.map(({id:m})=>R(l,m))??[]):[];if(e){const m=(...d)=>{f.logger.info(`[${n?g.basename(t):g.basename(g.join(t,"../../../../"))}] importAssets:`,...d)};try{m("wait image-bin api ready"),await It.default({resources:[`${Ee.getComponentWebEndpoint(f.IMAGE_BIN_NAME)}/api/sdk/uploads`],validateStatus:A=>A>=200&&A<=500}),m("image-bin api is ready");const d={},y={};m("start to upload assets"),await Promise.allSettled([Ue(h,d,{getFilePath:A=>l&&g.join(l,A),onFinish:A=>{m(`upload ${A.length} component assets`)}}),Ue(p,y,{getFilePath:(A,j)=>{const i=Pe.default(p,j.slice(0,1));return r&&g.join(r,g.dirname(i.slug),A)},onFinish:A=>{m(`upload ${A.length} page assets`)}})]),m("upload assets done"),Se.clear(),global.gc&&global.gc()}catch(d){m("Error during asset import:",d)}}const C={};if(s){const m=o&&g.join(g.dirname(o),"../../resources/components"),d=k(S.resources?.components?.map(({id:y})=>R(m,y))??[]);d.length>0&&(C.components=Object.fromEntries(d.map((y,A)=>[y.id,{index:A,component:y}])))}return{supportedLocales:S.supportedLocales,pageIds:p.map(m=>m.id),components:Object.fromEntries(h.map((m,d)=>[m.id,{index:d,data:m}])),pages:Object.fromEntries(p.map(m=>[m.id,m])),config:S.config||{},resources:C,routeIds:c.map(m=>m.id),routes:Object.fromEntries(c.map(m=>[m.id,m])),dataSourceIds:[],dataSources:{}}}finally{n&&a&&I.rmSync(a,{force:!0,recursive:!0})}}async function Ie(t,e,{routes:s,mergeMode:a="byUpdateTime",deleteRoutes:n=!1,publishMode:o=void 0}={}){try{o&&f.clearPreloadComponentsCacheByMode(o)}catch(b){f.logger.error("clear preload page cache error",{error:b})}const{pages:r,pageIds:l,routeIds:u,routes:S,supportedLocales:P}=t;if(o==="production"){let b=s??[],p=null;for(const c of u??[]){const h=S?.[c];if(h?.params&&h?.params.length>0&&h?.paramsOptions&&h?.paramsOptions.length>0){const C=Q.generateParamCombinations({basePath:h.path,params:h.params,routeId:h.id,paramsOptions:h.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]}),m=Object.fromEntries(C.map(d=>[`${c}-${d.paramOptionIds.join("-")}`,d]));p={...p||{},...m},s||(b=[...b,...C.map(d=>`${c}-${d.paramOptionIds.join("-")}`)])}else s||b.push(c)}f.logger.info("routeIds to be published: ",b);for(const c of b){let h=c;if(h.includes("-")){const[d]=h.split("-");h=d}const C=S?.[h];if(!C){const d=e.pageIds.indexOf(h);d!==-1&&n&&(e.pageIds.splice(d,1),delete e.pages[h]);for(const y of e.pageIds)y.includes(`${h}-`)&&(e.pageIds.splice(e.pageIds.indexOf(y),1),delete e.pages[y]);f.logger.info("delete main route page",h);continue}if(c.includes("-")&&!p?.[c]){const d=e.pageIds.indexOf(c);d!==-1&&n&&(e.pageIds.splice(d,1),delete e.pages[c]),f.logger.info("delete page",c);continue}if(!C.displayTemplateId){f.logger.info("no display template",c);continue}const m=r[C.displayTemplateId];if(!m){f.logger.info("no template page",c);continue}if(e.pageIds.includes(c)){if(f.logger.info("has need update page",c),a==="replace")e.pages[c]=de({page:m,route:C,state:t,routeId:c,routePathInfo:p?.[c]}),f.logger.info("replace page",c);else if(a==="byUpdateTime"){const d=e.pages[C.id];(!d||C.updatedAt&&C.updatedAt>d.updatedAt)&&(e.pages[c]=de({page:m,route:C,state:t,routeId:c,routePathInfo:p?.[c]}),f.logger.info("replace page by update time",c))}}else e.pageIds.push(c),e.pages[c]=de({page:m,route:C,state:t,routeId:c,routePathInfo:p?.[c]}),f.logger.info("add page",c)}if(n&&!s)for(const c of e.pageIds)b?.includes(c)||(delete e.pages[c],f.logger.info("delete page",c)),e.pageIds=[...e.pageIds].filter(h=>b?.includes(h))}else{for(const b of l){const p=r[b];if(p)if(e.pageIds.includes(p.id)){if(a==="replace")e.pages[p.id]=p;else if(a==="byUpdateTime"){const c=e.pages[p.id];(!c||p.updatedAt&&p.updatedAt>c.updatedAt)&&(e.pages[p.id]=p)}}else e.pageIds.push(p.id),e.pages[p.id]=p}for(const b of u){const p=S[b];if(p)if(e.routeIds.includes(p.id)){if(a==="replace")e.routes[p.id]=p;else if(a==="byUpdateTime"){const c=e.routes[p.id];(!c||p.updatedAt&&p.updatedAt>c.updatedAt)&&(e.routes[p.id]=p)}}else e.routeIds.push(p.id),e.routes[p.id]=p}}if(e.supportedLocales.splice(0,e.supportedLocales.length),e.supportedLocales.push(...we.default(P)),n)for(const b of Object.keys(e.components))delete e.components[b];let R=JSON.parse(JSON.stringify(t.components));R=Object.fromEntries(await Promise.all(Object.entries(R).map(async([b,p])=>{const c=await Ge(p?.data);return[b,{...p,data:c}]}))),Object.assign(e.components,R),Object.assign(e.config,JSON.parse(JSON.stringify(t.config))),Ae.default(t.resources.components)||(e.resources.components=JSON.parse(JSON.stringify(t.resources.components||{})))}const Ge=f.memoizeWithFs(async t=>{if(!Ae.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 f.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){f.logger.error("getPropertiesFromCode error",{componentId:t.id,name:t.name},{error:a})}}return t},{subdir:"getPropertiesFromCode"});let ae,J,oe,re;const Ve=()=>Ee.getResources({types:[{did:je,type:me},{did:Pt,type:me}]}),Vt=()=>{const t=Ve(),e={};return t.forEach(s=>{const a=Z.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 r of o)e[r]=g.join(n,r)}}),e};function ze(){return ae=(async()=>{const t=Ve();J=(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),oe=J.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=J.reduce((s,a)=>Object.assign(s,Object.fromEntries(Object.values(a.state.components).map(n=>[n.data.id,{blockletId:a.blockletId,component:n.data}]))),{});re=Object.fromEntries(await Promise.all(Object.entries(e).map(async([s,a])=>{const n=await Ge(a.component);return[s,{...a,component:n}]})))})(),ae}function Ye(t){const e=Me.default(async()=>{await ze().catch(s=>{f.logger.error("load resource states error",{error:s})}),await t?.({states:J,pages:oe,components:re})},3e3,{leading:!1,trailing:!0});return e(),w.default.events.on(w.default.Events.componentAdded,e),w.default.events.on(w.default.Events.componentRemoved,e),w.default.events.on(w.default.Events.componentStarted,e),w.default.events.on(w.default.Events.componentStopped,e),w.default.events.on(w.default.Events.componentUpdated,e),w.default.events.on(he,e),()=>{w.default.events.off(w.default.Events.componentAdded,e),w.default.events.off(w.default.Events.componentRemoved,e),w.default.events.off(w.default.Events.componentStarted,e),w.default.events.off(w.default.Events.componentStopped,e),w.default.events.off(w.default.Events.componentUpdated,e),w.default.events.off(he,e)}}const He=Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"),Ke=Symbol.for("GLOBAL_ENV_UPDATE_LISTENER_KEY"),ie=globalThis;ie[He]?.();ie[He]=Ye(async({pages:t,components:e})=>{const s=await O.getProjectIds();f.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=>{Je({projectId:a,pages:t,components:e})}))]).catch(a=>{f.logger.error("update resource states failed:",a)})});ie[Ke]?.();ie[Ke]=()=>{const t=()=>{O.pageUrlMapCache.clear(),f.logger.info("[Cache CLEAR ALL] clear all page url map cache by env update")};return w.default.events.on(w.default.Events.envUpdate,t),()=>{w.default.events.off(w.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 Je({projectId:t,pages:e,components:s}){const a=O.sharedInstances[t];if(!a){f.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 r=(await Oe.findAll({where:{projectId:t}})).map(u=>u.componentId),l=Object.fromEntries(Object.entries(s||{}).filter(([u])=>r.includes(u)));a.syncedStore.resources.components=l}f.logger.info(`update [${t}] resource states:`,{pages:Object.keys(a.syncedStore.resources.pages||{}).length,components:Object.keys(a.syncedStore.resources.components||{}).length})}async function We(t){return Je({projectId:t,pages:oe,components:re})}async function zt(){f.logger.info("trigger reload all project resource"),w.default.events.emit(he)}async function Yt({ensureLoaded:t=!0}={}){return t&&(ae??=ze(),await ae),{states:J,pages:oe,components:re}}exports.COMPONENT_DID=je;exports.PUBLISH_MODES=Bt;exports.Project=L;exports.RESOURCE_TYPE=me;exports.SITE_STATE_PATH=x;exports.STATE_MODES=xt;exports.SiteState=O;exports.downloadAsset=Fe;exports.downloadAssets=qe;exports.fromPackage=Ce;exports.getDefaultState=Ne;exports.getResourceStates=Yt;exports.initPackResourceStates=Ye;exports.mergeState=Ie;exports.toPackage=Be;exports.triggerReloadAllProjectResource=zt;exports.updateResourceStatesByProjectId=We;
|
package/lib/cjs/resources.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const g=require("./chunks/components-DLLpFRy5.js"),c=require("./chunks/site-state-
|
|
1
|
+
"use strict";const g=require("./chunks/components-DLLpFRy5.js"),c=require("./chunks/site-state-pWDDyjH2.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;
|
package/lib/cjs/site-state.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("./chunks/components-DLLpFRy5.js");const e=require("./chunks/site-state-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("./chunks/components-DLLpFRy5.js");const e=require("./chunks/site-state-pWDDyjH2.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]})});
|
|
@@ -5,7 +5,7 @@ import { setPageDataSource as rt } from "@blocklet/pages-kit/utils/data-source";
|
|
|
5
5
|
import { getRouteMetaDataByOptionIds as nt, generateParamCombinations as Ie } from "@blocklet/pages-kit/utils/route";
|
|
6
6
|
import Ee from "lodash/cloneDeep";
|
|
7
7
|
import E from "@blocklet/sdk/lib/config";
|
|
8
|
-
import { mkdtempSync as it, existsSync as M, readFileSync as J, renameSync as ve, mkdirSync as F, rmSync as _e, writeFileSync as te, copyFileSync as ct, lstatSync as
|
|
8
|
+
import { mkdtempSync as it, existsSync as M, readFileSync as J, renameSync as ve, mkdirSync as F, rmSync as _e, writeFileSync as te, copyFileSync as ct, lstatSync as B, readdirSync as lt, createWriteStream as pt } from "fs";
|
|
9
9
|
import { join as b, basename as k, dirname as L } from "path";
|
|
10
10
|
import { nextId as Re } from "@blocklet/pages-kit/utils/common";
|
|
11
11
|
import { unzipSection as ut } from "@blocklet/pages-kit/utils/page-model";
|
|
@@ -22,14 +22,14 @@ import je from "lodash/set";
|
|
|
22
22
|
import yt from "lodash/union";
|
|
23
23
|
import { LRUCache as Ae } from "lru-cache";
|
|
24
24
|
import St from "p-limit";
|
|
25
|
-
import { DataTypes as j, Sequelize as It, Model as xe, Op as
|
|
25
|
+
import { DataTypes as j, Sequelize as It, Model as xe, Op as Be } from "sequelize";
|
|
26
26
|
import { pipeline as Et } from "stream/promises";
|
|
27
27
|
import { x as bt } from "tar";
|
|
28
|
-
import { withoutTrailingSlash as
|
|
28
|
+
import { withoutTrailingSlash as Ge, withLeadingSlash as wt, joinURL as Y } from "ufo";
|
|
29
29
|
import At from "wait-on";
|
|
30
30
|
import { Awareness as Pt, encodeAwarenessUpdate as De, removeAwarenessStates as Ot, applyAwarenessUpdate as Ct } from "y-protocols/awareness";
|
|
31
31
|
import { writeUpdate as vt, writeSyncStep1 as Rt, readSyncMessage as jt } from "y-protocols/sync";
|
|
32
|
-
import * as
|
|
32
|
+
import * as G from "yaml";
|
|
33
33
|
import { m as Te } from "./html-DOgzvdOd.js";
|
|
34
34
|
import "sqlite3";
|
|
35
35
|
import "@blocklet/pages-kit/types/state";
|
|
@@ -139,16 +139,19 @@ const $t = "SLUG_INVALID", q = (t) => ({
|
|
|
139
139
|
], Le = (t) => {
|
|
140
140
|
if (!t) return "";
|
|
141
141
|
if (t === "/") return "/";
|
|
142
|
-
const e =
|
|
142
|
+
const e = Ge(t);
|
|
143
143
|
return wt(e) || "/";
|
|
144
144
|
}, Ft = (t) => t.did === Ut;
|
|
145
145
|
class U extends xe {
|
|
146
|
-
static async getProjectByIdOrSlug(e) {
|
|
147
|
-
return U.findOne({
|
|
146
|
+
static async getProjectByIdOrSlug(e, s) {
|
|
147
|
+
return e ? U.findOne({
|
|
148
148
|
where: {
|
|
149
|
-
[
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
[Be.or]: [{ id: e }, { slug: e }],
|
|
150
|
+
...s?.createdBy ? { createdBy: s.createdBy } : {}
|
|
151
|
+
},
|
|
152
|
+
// 软删除
|
|
153
|
+
paranoid: !1
|
|
154
|
+
}) : null;
|
|
152
155
|
}
|
|
153
156
|
static async validateProjectSlug({
|
|
154
157
|
slug: e,
|
|
@@ -169,7 +172,7 @@ class U extends xe {
|
|
|
169
172
|
return q((n) => `Project slug "${n}" contains invalid characters`);
|
|
170
173
|
if (E.components?.filter((n) => n.mountPoint && !Ft(n)).some((n) => Le(n.mountPoint) === o))
|
|
171
174
|
return q((n) => `Project slug "${n}" conflicts with existing blocklet`);
|
|
172
|
-
const r = await U.findOne({ where: { slug: e } });
|
|
175
|
+
const r = await U.findOne({ where: { slug: `${e}` } });
|
|
173
176
|
return r && r?.id !== s ? Nt : null;
|
|
174
177
|
}
|
|
175
178
|
}
|
|
@@ -280,7 +283,7 @@ function xt(t) {
|
|
|
280
283
|
});
|
|
281
284
|
});
|
|
282
285
|
}
|
|
283
|
-
function
|
|
286
|
+
function Bt(t) {
|
|
284
287
|
t.routes && Object.keys(t.routes).forEach((s) => {
|
|
285
288
|
const o = V(t.routes?.[s]);
|
|
286
289
|
o && o instanceof N.Map && oe(o);
|
|
@@ -295,7 +298,7 @@ function Gt(t) {
|
|
|
295
298
|
});
|
|
296
299
|
});
|
|
297
300
|
}
|
|
298
|
-
function
|
|
301
|
+
function Gt(t, e) {
|
|
299
302
|
for (const s of e || Object.keys(t.routes || {})) {
|
|
300
303
|
let o = s, a = [];
|
|
301
304
|
if (s.includes("-")) {
|
|
@@ -370,7 +373,7 @@ const Vt = 60 * 60 * 1e3, W = new Ae({
|
|
|
370
373
|
});
|
|
371
374
|
function zt(t, e = []) {
|
|
372
375
|
let s = 0;
|
|
373
|
-
const o = Array.from(W.keys()), a = t.map((r) =>
|
|
376
|
+
const o = Array.from(W.keys()), a = t.map((r) => Ge(r));
|
|
374
377
|
for (const r of o)
|
|
375
378
|
for (const n of a) {
|
|
376
379
|
if (Te(r, { currentPath: n })) {
|
|
@@ -498,7 +501,7 @@ class C extends N.Doc {
|
|
|
498
501
|
delete C.sharedInstances[e], super.destroy();
|
|
499
502
|
}
|
|
500
503
|
initObserver() {
|
|
501
|
-
xt(this.syncedStore),
|
|
504
|
+
xt(this.syncedStore), Bt(this.syncedStore);
|
|
502
505
|
}
|
|
503
506
|
get draftYjsFilePath() {
|
|
504
507
|
return b(this.options.path, "draft.yjs");
|
|
@@ -629,7 +632,7 @@ class C extends N.Doc {
|
|
|
629
632
|
const o = k(this.options.path);
|
|
630
633
|
await as(o);
|
|
631
634
|
const a = await this.getState("draft"), r = await this.getState("production");
|
|
632
|
-
await Me(a, r, { routes: s, mergeMode: "replace", deleteRoutes: !0, publishMode: e }), r.config.publishedAt = (/* @__PURE__ */ new Date()).getTime(),
|
|
635
|
+
await Me(a, r, { routes: s, mergeMode: "replace", deleteRoutes: !0, publishMode: e }), r.config.publishedAt = (/* @__PURE__ */ new Date()).getTime(), Gt(this.syncedStore, s), await this.setState(e, r), await this.clearPageCacheForRoutes(s, r);
|
|
633
636
|
};
|
|
634
637
|
mergeState = async (e, s) => {
|
|
635
638
|
const o = JSON.parse(JSON.stringify(s));
|
|
@@ -730,7 +733,7 @@ class C extends N.Doc {
|
|
|
730
733
|
const r = await U.findAll({
|
|
731
734
|
where: {
|
|
732
735
|
id: {
|
|
733
|
-
[
|
|
736
|
+
[Be.in]: o
|
|
734
737
|
}
|
|
735
738
|
}
|
|
736
739
|
});
|
|
@@ -877,7 +880,7 @@ class C extends N.Doc {
|
|
|
877
880
|
}
|
|
878
881
|
}
|
|
879
882
|
async function Qt(t, e, s) {
|
|
880
|
-
if (!t || !M(t) || !
|
|
883
|
+
if (!t || !M(t) || !B(t).isFile())
|
|
881
884
|
return null;
|
|
882
885
|
let o = s[t];
|
|
883
886
|
return o || (o = (async () => {
|
|
@@ -919,7 +922,7 @@ function Ke(t) {
|
|
|
919
922
|
}
|
|
920
923
|
async function ee(t, e, s) {
|
|
921
924
|
const { getFilename: o, exportAssets: a } = s, r = b(e, o(t));
|
|
922
|
-
if (F(L(r), { recursive: !0 }), te(r,
|
|
925
|
+
if (F(L(r), { recursive: !0 }), te(r, G.stringify(t)), a) {
|
|
923
926
|
const l = ae(
|
|
924
927
|
t,
|
|
925
928
|
(p) => typeof p == "string" && (Oe.test(p) || X.test(p))
|
|
@@ -1100,7 +1103,7 @@ async function ts(t, {
|
|
|
1100
1103
|
supportedLocales: t.supportedLocales,
|
|
1101
1104
|
config: t.config
|
|
1102
1105
|
};
|
|
1103
|
-
te(h,
|
|
1106
|
+
te(h, G.stringify(A));
|
|
1104
1107
|
const P = b(g, "config.source.json");
|
|
1105
1108
|
if (a && te(P, JSON.stringify(a)), r) {
|
|
1106
1109
|
const i = b(g, "resources"), S = b(i, "components");
|
|
@@ -1142,24 +1145,24 @@ async function qe(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1142
1145
|
return null;
|
|
1143
1146
|
let o, a = !1;
|
|
1144
1147
|
try {
|
|
1145
|
-
|
|
1148
|
+
B(t).isDirectory() ? o = t : /\.(tgz|gz|tar)$/.test(t) && (a = !0, o = ze(), await bt({ file: t, C: o }));
|
|
1146
1149
|
const r = se("**/.blocklet/pages/pages.config.yml", { cwd: o, absolute: !0 }).at(0), n = r && b(L(r), "../../pages"), l = r && b(L(r), "../../components"), p = r && b(L(r), "../../routes");
|
|
1147
1150
|
if (!r)
|
|
1148
1151
|
return null;
|
|
1149
|
-
const y =
|
|
1152
|
+
const y = G.parse(J(r).toString()), w = (m, d, h) => {
|
|
1150
1153
|
let A = b(m, `${d}${h ? `.${h}` : ""}.yml`);
|
|
1151
|
-
return (!M(A) || !
|
|
1154
|
+
return (!M(A) || !B(A).isFile()) && (A = b(m, d, `index${h ? `.${h}` : ""}.yml`), !M(A) || !B(A)) ? null : G.parse(J(A).toString());
|
|
1152
1155
|
}, R = (m, d) => {
|
|
1153
1156
|
try {
|
|
1154
1157
|
const h = se(`*.${d}.yml`, { cwd: m, absolute: !0 })[0];
|
|
1155
|
-
return h ?
|
|
1158
|
+
return h ? G.parse(J(h).toString()) : null;
|
|
1156
1159
|
} catch (h) {
|
|
1157
1160
|
f.error("parse component error", h);
|
|
1158
1161
|
}
|
|
1159
1162
|
return null;
|
|
1160
1163
|
}, I = (m, d) => {
|
|
1161
1164
|
let h = b(m, `${d}.yml`);
|
|
1162
|
-
return (!M(h) || !
|
|
1165
|
+
return (!M(h) || !B(h).isFile()) && (h = b(m, d, "index.yml"), !M(h) || !B(h)) ? null : G.parse(J(h).toString());
|
|
1163
1166
|
}, u = T(
|
|
1164
1167
|
y.pages.map(({ slug: m }) => {
|
|
1165
1168
|
const d = T(
|
package/lib/es/resources.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as A, a as M, l as b } from "./chunks/components-DLwSTd_N.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-
|
|
2
|
+
import { P as w, C as J, R as X, S as x, t as W, g as G } from "./chunks/site-state-Ia5YbZtX.js";
|
|
3
3
|
import { Router as K } from "express";
|
|
4
4
|
import a from "fs";
|
|
5
5
|
import m from "joi";
|
package/lib/es/site-state.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./chunks/components-DLwSTd_N.js";
|
|
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-
|
|
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-Ia5YbZtX.js";
|
|
3
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";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/pages-kit-inner-components",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.88",
|
|
4
4
|
"description": "Pages Kit inner components library",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -201,8 +201,8 @@
|
|
|
201
201
|
"yaml": "^2.5.0",
|
|
202
202
|
"yjs": "^13.6.18",
|
|
203
203
|
"zustand": "^4.5.5",
|
|
204
|
-
"@blocklet/pages-kit
|
|
205
|
-
"@blocklet/pages-kit": "^0.6.
|
|
204
|
+
"@blocklet/pages-kit": "^0.6.88",
|
|
205
|
+
"@blocklet/pages-kit-block-studio": "^0.6.88"
|
|
206
206
|
},
|
|
207
207
|
"devDependencies": {
|
|
208
208
|
"@trivago/prettier-plugin-sort-imports": "^5.2.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const f=require("./components-DLLpFRy5.js"),q=require("@syncedstore/core"),Qe=require("yjs"),Ze=require("@blocklet/pages-kit/utils/data-source"),Q=require("@blocklet/pages-kit/utils/route"),et=require("lodash/cloneDeep"),tt=require("@blocklet/sdk/lib/config"),I=require("fs"),g=require("path"),Re=require("@blocklet/pages-kit/utils/common"),st=require("@blocklet/pages-kit/utils/page-model"),at=require("@blocklet/pages-kit/utils/property"),Ee=require("@blocklet/sdk/lib/component"),nt=require("@reactivedata/reactive"),Z=require("glob"),ot=require("lib0/decoding"),rt=require("lib0/encoding"),it=require("lodash/debounce"),ct=require("lodash/get"),lt=require("lodash/isEmpty"),ut=require("lodash/set"),pt=require("lodash/union"),be=require("lru-cache"),dt=require("p-limit"),T=require("sequelize"),ft=require("stream/promises"),gt=require("tar"),F=require("ufo"),mt=require("wait-on"),z=require("y-protocols/awareness"),ue=require("y-protocols/sync"),ht=require("yaml"),ve=require("./html-xfTPTsl5.js");require("sqlite3");require("@blocklet/pages-kit/types/state");const $=t=>t&&t.__esModule?t:{default:t};function ne(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 U=ne(Qe),we=$(et),w=$(tt),pe=ne(ot),v=ne(rt),Me=$(it),Pe=$(ct),Ae=$(lt),ke=$(ut),yt=$(pt),St=$(dt),It=$(mt),B=ne(ht),Et=T.DataTypes.sqlite.DATE.parse;T.DataTypes.sqlite.DATE.parse=(t,e)=>typeof t=="number"?new Date(t):Et(t,e);const M=new T.Sequelize({dialect:"sqlite",storage:f.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});M.query("pragma journal_mode = WAL;");M.query("pragma synchronous = normal;");M.query("pragma journal_size_limit = 33554432;");M.query("pragma cache_size = -2000;");M.query("pragma mmap_size = 33554432;");process.on("SIGINT",async()=>{await M.close(),process.exit(0)});process.on("SIGTERM",async()=>{await M.close(),process.exit(0)});async function bt(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 ge=null;ge&&clearInterval(ge);ge=setInterval(async()=>{f.logger.info("Start cleanupSqliteMemory"),await bt(M,f.databaseUrl),f.logger.info("End cleanupSqliteMemory")},60*1e3*10);const wt="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o",me="page",he="trigger-reload-project-resource",je=wt,Pt="z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM",At="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o";class Oe extends T.Model{}Oe.init({id:{type:T.DataTypes.UUID,allowNull:!1,primaryKey:!0,defaultValue:T.DataTypes.UUIDV4},projectId:{type:T.DataTypes.UUID,allowNull:!1},componentId:{type:T.DataTypes.STRING,allowNull:!1}},{sequelize:M,tableName:"ProjectComponents",timestamps:!1});const jt="SLUG_INVALID",Y=t=>({error:"slugInvalid",code:jt,field:"slug",message:t}),Ot={error:"slugRequired",code:"SLUG_REQUIRED",field:"slug",message:()=>"Project slug is required"},Tt={error:"slugAlreadyExists",code:"SLUG_EXISTS",field:"slug",message:t=>`Project slug "${t}" already exists`},Ct=[/\.\./,/<[^>]*>/,/%[0-9a-f]{2}/i,/[<>'"%;{}()\\]/,/\x00/,/\n|\r|\t|\v|\f/,/[^a-zA-Z0-9-_@/\\:]/],Le=t=>{if(!t)return"";if(t==="/")return"/";const e=F.withoutTrailingSlash(t);return F.withLeadingSlash(e)||"/"},Dt=t=>t.did===At;class L extends T.Model{static async getProjectByIdOrSlug(e){return L.findOne({where:{[T.Op.or]:[{id:e},{slug:e}]}})}static async validateProjectSlug({slug:e,projectId:s}){if(e==null)return null;if(e==="")return Ot;const a=Le(e);if(e!=="/"&&e.endsWith("/"))return Y(r=>`Project slug "${r}" cannot end with /`);if(/\/{2,}/.test(e))return Y(r=>`Project slug "${r}" cannot contain consecutive /`);if(/\s/.test(e))return Y(r=>`Project slug "${r}" cannot contain whitespace`);if(Ct.some(r=>r.test(e)))return Y(r=>`Project slug "${r}" contains invalid characters`);if(w.default.components?.filter(r=>r.mountPoint&&!Dt(r)).some(r=>Le(r.mountPoint)===a))return Y(r=>`Project slug "${r}" conflicts with existing blocklet`);const o=await L.findOne({where:{slug:e}});return o&&o?.id!==s?Tt:null}}L.init({id:{type:T.DataTypes.UUID,defaultValue:T.DataTypes.UUIDV4,primaryKey:!0},name:{type:T.DataTypes.STRING,allowNull:!1},description:T.DataTypes.TEXT,createdAt:T.DataTypes.DATE,updatedAt:T.DataTypes.DATE,createdBy:{type:T.DataTypes.STRING,allowNull:!1},updatedBy:{type:T.DataTypes.STRING,allowNull:!1},slug:T.DataTypes.STRING,icon:T.DataTypes.STRING,pinnedAt:T.DataTypes.DATE,useAllResources:T.DataTypes.BOOLEAN,npmSecret:T.DataTypes.STRING,relatedBlocklets:{type:T.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 f.logger.error("Failed to parse relatedBlocklets",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("relatedBlocklets",t?JSON.stringify(t):"{}")}catch(e){f.logger.error("Failed to set relatedBlocklets",{error:e,value:t}),this.setDataValue("relatedBlocklets","{}")}}},productionState:{type:T.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 f.logger.error("Failed to parse productionState",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("productionState",t?JSON.stringify(t):"{}")}catch(e){f.logger.error("Failed to set productionState",{error:e,value:t}),this.setDataValue("productionState","{}")}}}},{sequelize:M,paranoid:!0});L.hasMany(Oe,{foreignKey:"projectId",as:"components"});function ee(t){t.observeDeep(e=>{e.some(s=>s.changes.keys.has("updatedAt")||s.changes.keys.has("publishedAt"))||t.set("updatedAt",new Date().toISOString())})}function $e(){return I.mkdtempSync(g.join(w.default.env.dataDir,"tmp-"))}function te(t,e,s=[]){return Array.isArray(t)?t.flatMap((a,n)=>te(a,e,[...s,n])):typeof t=="object"?t===null?[]:Object.entries(t).flatMap(([a,n])=>te(n,e,[...s,a])):e(t)?[s]:[]}function k(t){return t.filter(e=>e!=null)}function Rt(t){t.pages&&Object.keys(t.pages).forEach(s=>{const a=q.getYjsValue(t.pages[s]);a&&a instanceof U.Map&&ee(a)});const e=q.getYjsValue(t.pages);e&&e instanceof U.Map&&e.observe(s=>{s.changes.keys.forEach((a,n)=>{if(a.action==="add"){const o=q.getYjsValue(t.pages[n]);o&&o instanceof U.Map&&ee(o)}})})}function vt(t){t.routes&&Object.keys(t.routes).forEach(s=>{const a=q.getYjsValue(t.routes?.[s]);a&&a instanceof U.Map&&ee(a)});const e=q.getYjsValue(t.routes);e&&e instanceof U.Map&&e.observe(s=>{s.changes.keys.forEach((a,n)=>{if(a.action==="add"){const o=q.getYjsValue(t.routes?.[n]);o&&o instanceof U.Map&&ee(o)}})})}function kt(t,e){for(const s of e||Object.keys(t.routes||{})){let a=s,n=[];if(s.includes("-")){const[o,...r]=s.split("-");a=o,n=r||[]}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 r=Q.getRouteMetaDataByOptionIds(n,o);r&&(r.publishedAt=new Date().toISOString())}if(!e){const r=Q.generateParamCombinations({basePath:o.path,params:o.params,routeId:o.id,paramsOptions:o.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const l of r)l.routeMetaData??={},l.routeMetaData.publishedAt=new Date().toISOString()}}}}function de({page:t,route:e,state:s,routeId:a,routePathInfo:n}){f.logger.info(`Executing datasource data assembly, routeId: ${a}, routePathInfo: ${JSON.stringify(n)}`);const o={...we.default(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 r of s.supportedLocales){if(e.dataSource){let l=e.id;n&&(l=n.paramOptionIds.join("-"));const u=e.dataSource.pathDataMappings?.[l]?.dataCache?.[r.locale]??e.dataSource.pathDataMappings?.[l]?.dataCache?.[s.config.defaultLocale||"en"];if(!u)continue;Ze.setPageDataSource(o,s,r.locale,u)}n&&n.routeMetaData&&(n.routeMetaData.publishedAt=new Date().toISOString())}return o}["true","1","yes","y"].includes(process.env.USE_FS_CACHE_HTML??"");const Lt=60*60*1e3,H=new be.LRUCache({max:100,ttl:Lt,ttlResolution:10*1e3,allowStale:!0});function _t(t,e=[]){let s=0;const a=Array.from(H.keys()),n=t.map(o=>F.withoutTrailingSlash(o));for(const o of a)for(const r of n){if(ve.matchCacheKey(o,{currentPath:r})){H.delete(o),s++,f.logger.info(`[Cache CLEAR] key: ${o}`);break}for(const l of e)if(ve.matchCacheKey(o,{currentPath:`/${l}${r}`})){H.delete(o),s++,f.logger.info(`[Cache CLEAR] key: ${o}`);break}}return f.logger.info(`[Cache CLEAR] cleared ${s} entries for paths:`,n),s}function Ut(){const t=H.size;return H.clear(),f.logger.info(`[Cache CLEAR ALL] cleared ${t} entries`),t}w.default.events.on(w.default.Events.envUpdate,Ut);const{uploadToMediaKit:Mt}=require("@blocklet/uploader-server"),Te=/^\w+(\w|-|\.)+\w+\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm)$/,K=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/i,_e=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/gi,$t=1e4,Nt=3e4,W=0,fe=1,Ft=0,qt=1,ye=w.default,x=g.join(process.env.BLOCKLET_DATA_DIR,"site-state"),xt=["production","draft"],Bt=["production"];function se(t){return t?.replace(/\//g,"|")||""}function Ne(){const t=ye.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 U.Doc{constructor(e){super(),this.options=e,I.existsSync(this.draftYjsFilePath)&&U.applyUpdate(this,I.readFileSync(this.draftYjsFilePath)),this.syncedStore=nt.reactive(q.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(x,e),a=g.join(x,`@del-${e}`);I.renameSync(s,a)}catch(s){f.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 Z.globSync("*/",{cwd:x,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(x,e)}),O.sharedInstances[e]=s,s)}static async getProductionState(e){const s=await L.findByPk(e,{attributes:["productionState"]});if(Ae.default(s?.productionState)){const a=g.join(x,e,"production"),n=await Ce(a,{includeResources:!0})??Ne();if(!n?.config?.defaultLocale){n.config??={};const o=ye.env.languages?.map(r=>({locale:r.code,name:r.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(){Rt(this.syncedStore),vt(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 Be(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);const r=we.default(s);await L.update({productionState:r},{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 u=this.conns.get(n);u&&(e.forEach(S=>{u.add(S)}),a.forEach(S=>{u.delete(S)}))}const r=v.createEncoder();v.writeVarUint(r,fe),v.writeVarUint8Array(r,z.encodeAwarenessUpdate(this.awareness,o));const l=v.toUint8Array(r);this.conns.forEach((u,S)=>this.send(S,l))};updateHandler=e=>{const s=v.createEncoder();v.writeVarUint(s,W),ue.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:r}=this.syncedStore;{const l=new Set(Object.keys(s));let u=0;for(;u<a.length;){const S=a[u];l.has(S)?(l.delete(S),u++):a.splice(u,1)}}{const l=new Set(Object.keys(o));let u=0;for(;u<r.length;){const S=r[u];l.has(S)?(l.delete(S),u++):r.splice(u,1)}}e.splice(0,e.length),e.push(...ye.env.languages.map(l=>({locale:l.code,name:l.name}))),n.defaultLocale=e[0]?.locale;{let l=0;const u=new Set;for(;l<e.length;){const{locale:S}=e[l];u.has(S)?e.splice(l,1):(l++,u.add(S))}}};send=(e,s)=>{e.readyState!==Ft&&e.readyState!==qt&&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(()=>{f.logger.info(`[SiteState] releasing instance due to no active connections: ${e}`),this.conns.size===0&&(this.releaseTimer=void 0,this.destroy())},O.RELEASE_DELAY),f.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);f.logger.info(`[SiteState] cancelled scheduled release for project ${e}`)}}autoSave=Me.default(()=>{I.mkdirSync(g.dirname(this.draftYjsFilePath),{recursive:!0}),I.writeFileSync(this.draftYjsFilePath,U.encodeStateAsUpdate(this))},$t);save=({flush:e=!1}={})=>{this.autoSave(),e&&this.autoSave.flush()};publish=async({mode:e,routes:s})=>{const a=g.basename(this.options.path);await We(a);const n=await this.getState("draft"),o=await this.getState("production");await Ie(n,o,{routes:s,mergeMode:"replace",deleteRoutes:!0,publishMode:e}),o.config.publishedAt=new Date().getTime(),kt(this.syncedStore,s),await this.setState(e,o),await this.clearPageCacheForRoutes(s,o)};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((r,l)=>{this.transact(async()=>{try{const u=await Ie(e,s);r(u)}catch(u){l(u)}})})};clearPageCacheForRoutes=async(e,s)=>{const a=g.basename(this.options.path),o=(await L.findByPk(a))?.slug||a;let r=e;(!r||r.length===0)&&(r=s.pageIds??[]),f.logger.info(`[SiteState] clearing page cache for project ${a}, routes:`,r||[]);const l=s.supportedLocales.map(P=>P.locale),u=[],S=r.filter(P=>s.pageIds?.includes(P));for(const P of S){const b=s.pages[P].slug;o&&o!==a&&(o==="/"?u.push(b):u.push(`/${o}${b}`)),u.push(`/${a}${b}`)}if(u.length>0)try{const P=_t(u,l);f.logger.info(`[SiteState] cleared ${P} page cache entries for project ${a}, routes:`,r)}catch{}};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)}}},Nt);e.on("close",()=>{this.closeConn(e),clearInterval(a)}),e.on("pong",()=>{s=!0});{const n=v.createEncoder();v.writeVarUint(n,W),ue.writeSyncStep1(n,this),this.send(e,v.toUint8Array(n));const o=this.awareness.getStates();if(o.size>0){const r=v.createEncoder();v.writeVarUint(r,fe),v.writeVarUint8Array(r,z.encodeAwarenessUpdate(this.awareness,Array.from(o.keys()))),this.send(e,v.toUint8Array(r))}}};messageListener=(e,s)=>{try{const a=v.createEncoder(),n=pe.createDecoder(s),o=pe.readVarUint(n);switch(o){case W:v.writeVarUint(a,W),ue.readSyncMessage(n,a,this,null),v.length(a)>1&&(this.ensureDataStructure(),this.send(e,v.toUint8Array(a)));break;case fe:{z.applyAwarenessUpdate(this.awareness,pe.readVarUint8Array(n),e);break}default:f.logger.warn(`Unsupported messageType ${o}`)}}catch(a){f.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(r=>[r,!0])||[]);for(const r of a){const l=O.pageUrlMapCache.get(r);l&&(n={...n,...l},o.delete(r))}a=Array.from(o.keys())}if(a?.length){const o=await L.findAll({where:{id:{[T.Op.in]:a}}});await Promise.all(o?.map(async r=>{const l=r.id,u=r.slug||l,S={},P=e==="production"&&r?.productionState?r.productionState:await O.getStateByProjectId(r.id,e),R=yt.default(w.default.env.languages?.map(p=>p.code)||[],P.supportedLocales?.map(p=>p.locale)||[]),b=(p,c)=>{u&&(S[F.joinURL("/",u,p)]={...c,shouldRedirect:!0,mainPage:!0}),S[F.joinURL("/",l,p)]={...c,shouldRedirect:!0,mainPage:!0};for(const h of R){const C={...c,locale:h};S[F.joinURL("/",h,l,p)]=C,u&&(S[F.joinURL("/",h,u,p)]=C)}};if(e==="draft")for(const p of P.routeIds||[]){const c=P?.routes?.[p];if(!c)continue;if(c.params&&c.params.length>0){const m=Q.generateParamCombinations({basePath:c.path,params:c.params,routeId:c.id,paramsOptions:c.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const d of m){const y=d.path,A={projectId:l,projectSlug:u,pageSlug:y,pageId:c.displayTemplateId||"",routeId:p,defaultLocale:R?.[0],locales:R,publishedAt:P.config.publishedAt,isPublic:c.isPublic&&d?.routeMetaData?.isPublic};b(y,A)}}const h=c.path,C={projectId:l,projectSlug:u,pageSlug:h,pageId:c.displayTemplateId||"",routeId:p,defaultLocale:R?.[0],locales:R,publishedAt:P.config.publishedAt,isPublic:c.isPublic};b(h,C)}for(const p of P.pageIds||[]){const c=P.pages[p];if(!c||e==="production"&&!c.isPublic)continue;const h=c.slug,C=r.slug||l,m={projectId:l,projectSlug:C,pageSlug:h,pageId:p,defaultLocale:R?.[0],locales:R,publishedAt:P.config.publishedAt,isPublic:c.isPublic,templateConfig:c.templateConfig};b(h,m)}e==="production"&&O.pageUrlMapCache.set(l,S),n={...n,...S}}))}return n}getDocumentSize(){return U.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),f.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,f.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(f.logger.info(`[SiteState] periodic check summary: total instances: ${e}, with connections: ${a.length}, without connections: ${s.length}`),s.length>0){f.logger.info(`[SiteState] releasing ${s.length} instances without connections:`,s.map(o=>o.projectId));let n=0;for(const{projectId:o,instance:r}of s)try{f.logger.info(`[SiteState] releasing instance due to periodic check: ${o}`),r.destroy(),n++}catch(l){f.logger.error(`[SiteState] failed to release instance ${o} during periodic check:`,l)}f.logger.info(`[SiteState] periodic check completed: ${n}/${s.length} instances released successfully`)}else e>0?f.logger.debug("[SiteState] periodic check: all instances have active connections"):f.logger.debug("[SiteState] periodic check: no instances exist")}}async function Gt(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 Mt({filePath:t,fileName:e}))?.data?.filename}catch(n){return f.logger.error(`Failed to upload asset ${t}:`,n),null}})(),s[t]=a),a}const Fe=async(t,e)=>{const s=g.basename(t),a=await Ee.call({name:je,path:F.joinURL("/uploads",s),responseType:"stream",method:"GET"});if(a.status>=200&&a.status<400){const n=I.createWriteStream(e);await ft.pipeline(a.data,n)}else throw new Error(`download asset failed ${a.status}`)},qe=async(t,e)=>{await Promise.all(t.map(async s=>{try{await Fe(s,g.join(e,g.basename(s)))}catch(a){f.logger.error(`Failed to export assets: ${s}, ${a}`)}}))};function xe(t){return Te.test(t)?[t]:K.test(t)?(_e.lastIndex=0,Array.from(t.matchAll(_e)).map(s=>s[1]).filter(s=>!!s)):[]}async function X(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,B.stringify(t)),n){const l=te(t,u=>typeof u=="string"&&(Te.test(u)||K.test(u))).map(u=>{const S=Pe.default(t,u);return xe(S)}).flat().filter(Boolean);await qe(l,g.dirname(o))}}const Se=new be.LRUCache({max:100,ttl:1*60*1e3});async function Ue(t,e,s){const a=te(t,l=>typeof l=="string"&&(Te.test(l)||K.test(l))),n=St.default(2),o=a.map(l=>n(async()=>{try{const u=Pe.default(t,l),S=xe(u);for(const P of S){const R=g.basename(P),b=s.getFilePath(P,l),p=b?`${b}:${R}`:R,c=Se.get(p);if(c){K.test(u)||ke.default(t,l,c);return}const h=await Gt(b,R,e);h&&(K.test(u)||ke.default(t,l,h),Se.set(p,h))}}catch(u){f.logger.error(`Failed to process upload for path ${l.join(".")}:`,u.message||u.reason)}})),r=await Promise.allSettled(o);s.onFinish?.(r)}async function Be(t,{exportAssets:e,pageIds:s="all",componentIds:a="all",rawConfig:n,includeResources:o=!1,routeIds:r="all"}={}){const l=s==="all"?t.pageIds:s,u=at.getComponentDependencies({state:t,pageIds:l,componentIds:a==="all"?Object.keys(t.components):a});Object.entries(t.components).forEach(([i,E])=>{E.data?.renderer?.type==="component-template"&&u.push(i)});const S=r==="all"?t.routeIds:r,P=i=>({id:i.id,name:i.name,isTemplateSection:i.isTemplateSection??!1,templateDescription:i.templateDescription,component:i.component,config:i.config,visibility:i.visibility,sections:i?.sectionIds?k(i?.sectionIds?.map(E=>{const D=i.sections?.[E];return D&&P(D)})):void 0}),R=(i,E)=>({id:i.id,createdAt:i.createdAt,updatedAt:i.updatedAt,publishedAt:i.publishedAt,isPublic:i.isPublic??!0,templateConfig:i.templateConfig,meta:i.locales?.[E]??{},sections:k(i.sectionIds.map(D=>{const N=i.sections[D];return N&&P(N)})),dataSource:Object.fromEntries(Object.entries(i.dataSource||{}).map(([D,N])=>[D,N?.[E]??{}]))}),b=i=>({id:i.id,createdAt:i.createdAt,updatedAt:i.updatedAt,publishedAt:i.publishedAt,path:i.path,handler:i.handler,isPublic:i.isPublic??!0,params:i.params??[],enabledGenerate:i.enabledGenerate??!1,displayTemplateId:i.displayTemplateId,dataSource:i.dataSource}),p=k(S.map(i=>{const E=t.routes[i];return E&&b(E)})),c=k(t.supportedLocales.map(i=>i.locale).flatMap(i=>l.map(E=>{const D=t.pages[E];return D&&{locale:i,slug:D.slug,page:R(D,i)}}))),h=$e(),C=g.join(h,"pages");I.mkdirSync(C,{recursive:!0});const m=g.join(h,"components");I.mkdirSync(m,{recursive:!0});const d=g.join(h,"routes");I.mkdirSync(d,{recursive:!0});for(const{locale:i,slug:E,page:D}of c)await X(D,C,{getFilename:()=>`${se(E)||"index"}.${i}.yml`,exportAssets:e});for(const i of p)await X(i,d,{getFilename:()=>`${se(i.path)||"index"}.yml`,exportAssets:e});for(const i of u){const E=t.components[i]?.data;E&&await X(E,m,{getFilename:D=>`${D.name||"unnamed"}.${D.id}.yml`,exportAssets:e})}const y=g.join(h,".blocklet/pages/pages.config.yml");I.mkdirSync(g.dirname(y),{recursive:!0});const A={pages:k(l.map(i=>{const E=t.pages[i];return E&&{id:i,slug:E.slug}})),routes:k(S.map(i=>{const E=t.routes[i];return E&&{id:i,path:E.path}})),components:k(u.map(i=>{const E=t.components[i]?.data;return E&&{id:i,name:E.name}})),...o?{resources:{components:k(Object.keys(t.resources?.components||{}).filter(i=>u.includes(i)).map(i=>({id:i,name:t.resources?.components?.[i]?.component?.name})))}}:{},supportedLocales:t.supportedLocales,config:t.config};I.writeFileSync(y,B.stringify(A));const j=g.join(h,"config.source.json");if(n&&I.writeFileSync(j,JSON.stringify(n)),o){const i=g.join(h,"resources"),E=g.join(i,"components");I.mkdirSync(E,{recursive:!0});for(const G of Object.keys(t?.resources?.components??{}).filter(_=>u.includes(_))){const _=t.resources?.components?.[G]?.component;_&&await X(_,E,{getFilename:V=>`${V.name||"unnamed"}.${V.id}.yml`,exportAssets:e})}const D=g.join(h,"chunks");I.mkdirSync(D,{recursive:!0});const N=Vt();for(const G of Object.keys(t?.resources?.components??{}).filter(_=>u.includes(_))){const _=t.resources?.components?.[G]?.component;if(_&&_.renderer?.type==="react-component"){const V=_.renderer?.chunks??[];if(V?.length>0)for(const ce of V){const De=g.join(D,ce),le=N?.[ce];try{le&&I.existsSync(le)&&!I.existsSync(De)&&I.copyFileSync(le,De)}catch(Xe){f.logger.error(`copy chunk ${ce} error`,Xe.message)}}}}}return h}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=$e(),await gt.x({file:t,C:a}));const o=Z.globSync("**/.blocklet/pages/pages.config.yml",{cwd:a,absolute:!0}).at(0),r=o&&g.join(g.dirname(o),"../../pages"),l=o&&g.join(g.dirname(o),"../../components"),u=o&&g.join(g.dirname(o),"../../routes");if(!o)return null;const S=B.parse(I.readFileSync(o).toString()),P=(m,d,y)=>{let A=g.join(m,`${d}${y?`.${y}`:""}.yml`);return(!I.existsSync(A)||!I.lstatSync(A).isFile())&&(A=g.join(m,d,`index${y?`.${y}`:""}.yml`),!I.existsSync(A)||!I.lstatSync(A))?null:B.parse(I.readFileSync(A).toString())},R=(m,d)=>{try{const y=Z.globSync(`*.${d}.yml`,{cwd:m,absolute:!0})[0];return y?B.parse(I.readFileSync(y).toString()):null}catch(y){f.logger.error("parse component error",y)}return null},b=(m,d)=>{let y=g.join(m,`${d}.yml`);return(!I.existsSync(y)||!I.lstatSync(y).isFile())&&(y=g.join(m,d,"index.yml"),!I.existsSync(y)||!I.lstatSync(y))?null:B.parse(I.readFileSync(y).toString())},p=k(S.pages.map(({slug:m})=>{const d=k(S.supportedLocales.map(({locale:j})=>{const i=r?P(r,se(m),j):void 0;if(i)return{locale:j,page:i};const E=r?P(r,m,j):void 0;return E&&{locale:j,page:E}})),y=d[0]?.page;if(!y)return null;const A=y.sections.map(st.unzipSection);return{id:y.id||Re.nextId(),createdAt:y.createdAt,updatedAt:y.updatedAt,publishedAt:y.publishedAt,isPublic:y.isPublic??!0,templateConfig:y.templateConfig,slug:m,sections:Object.fromEntries(A.map(j=>[j.id,j])),sectionIds:A.map(j=>j.id),locales:Object.fromEntries(d.map(({locale:j,page:i})=>[j,i.meta])),dataSource:y.dataSource?Object.fromEntries([...new Set(d.flatMap(({page:j})=>Object.keys(j.dataSource??{})))].map(j=>[j,Object.fromEntries(d.map(({locale:i,page:E})=>{const D=E.dataSource?.[j];return[i,D||{}]}))])):Object.fromEntries([...new Set(d.flatMap(({page:j})=>j.sections.map(i=>i.id)))].map(j=>[j,Object.fromEntries(d.map(({locale:i,page:E})=>{const D=E.dataSource?.[j];if(D)return[i,D];const N=E.sections.find(G=>G.id===j);return[i,N?.properties||{}]}))]))}})),c=k(S?.routes?.map(({path:m})=>{const d=u?b(u,se(m)):void 0;return{...d,id:d?.id||Re.nextId(),createdAt:d?.createdAt??new Date().toISOString(),updatedAt:d?.updatedAt??new Date().toISOString(),publishedAt:new Date(0).toISOString(),path:d?.path??`/${d?.id}`,params:d?.params,handler:d?.handler??"Pages Kit",isPublic:d?.isPublic??!0,enabledGenerate:d?.enabledGenerate??!1,displayTemplateId:d?.displayTemplateId??void 0,dataSource:d?.dataSource??{}}})??[]),h=l?k(S.components?.map(({id:m})=>R(l,m))??[]):[];if(e){const m=(...d)=>{f.logger.info(`[${n?g.basename(t):g.basename(g.join(t,"../../../../"))}] importAssets:`,...d)};try{m("wait image-bin api ready"),await It.default({resources:[`${Ee.getComponentWebEndpoint(f.IMAGE_BIN_NAME)}/api/sdk/uploads`],validateStatus:A=>A>=200&&A<=500}),m("image-bin api is ready");const d={},y={};m("start to upload assets"),await Promise.allSettled([Ue(h,d,{getFilePath:A=>l&&g.join(l,A),onFinish:A=>{m(`upload ${A.length} component assets`)}}),Ue(p,y,{getFilePath:(A,j)=>{const i=Pe.default(p,j.slice(0,1));return r&&g.join(r,g.dirname(i.slug),A)},onFinish:A=>{m(`upload ${A.length} page assets`)}})]),m("upload assets done"),Se.clear(),global.gc&&global.gc()}catch(d){m("Error during asset import:",d)}}const C={};if(s){const m=o&&g.join(g.dirname(o),"../../resources/components"),d=k(S.resources?.components?.map(({id:y})=>R(m,y))??[]);d.length>0&&(C.components=Object.fromEntries(d.map((y,A)=>[y.id,{index:A,component:y}])))}return{supportedLocales:S.supportedLocales,pageIds:p.map(m=>m.id),components:Object.fromEntries(h.map((m,d)=>[m.id,{index:d,data:m}])),pages:Object.fromEntries(p.map(m=>[m.id,m])),config:S.config||{},resources:C,routeIds:c.map(m=>m.id),routes:Object.fromEntries(c.map(m=>[m.id,m])),dataSourceIds:[],dataSources:{}}}finally{n&&a&&I.rmSync(a,{force:!0,recursive:!0})}}async function Ie(t,e,{routes:s,mergeMode:a="byUpdateTime",deleteRoutes:n=!1,publishMode:o=void 0}={}){try{o&&f.clearPreloadComponentsCacheByMode(o)}catch(b){f.logger.error("clear preload page cache error",{error:b})}const{pages:r,pageIds:l,routeIds:u,routes:S,supportedLocales:P}=t;if(o==="production"){let b=s??[],p=null;for(const c of u??[]){const h=S?.[c];if(h?.params&&h?.params.length>0&&h?.paramsOptions&&h?.paramsOptions.length>0){const C=Q.generateParamCombinations({basePath:h.path,params:h.params,routeId:h.id,paramsOptions:h.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]}),m=Object.fromEntries(C.map(d=>[`${c}-${d.paramOptionIds.join("-")}`,d]));p={...p||{},...m},s||(b=[...b,...C.map(d=>`${c}-${d.paramOptionIds.join("-")}`)])}else s||b.push(c)}f.logger.info("routeIds to be published: ",b);for(const c of b){let h=c;if(h.includes("-")){const[d]=h.split("-");h=d}const C=S?.[h];if(!C){const d=e.pageIds.indexOf(h);d!==-1&&n&&(e.pageIds.splice(d,1),delete e.pages[h]);for(const y of e.pageIds)y.includes(`${h}-`)&&(e.pageIds.splice(e.pageIds.indexOf(y),1),delete e.pages[y]);f.logger.info("delete main route page",h);continue}if(c.includes("-")&&!p?.[c]){const d=e.pageIds.indexOf(c);d!==-1&&n&&(e.pageIds.splice(d,1),delete e.pages[c]),f.logger.info("delete page",c);continue}if(!C.displayTemplateId){f.logger.info("no display template",c);continue}const m=r[C.displayTemplateId];if(!m){f.logger.info("no template page",c);continue}if(e.pageIds.includes(c)){if(f.logger.info("has need update page",c),a==="replace")e.pages[c]=de({page:m,route:C,state:t,routeId:c,routePathInfo:p?.[c]}),f.logger.info("replace page",c);else if(a==="byUpdateTime"){const d=e.pages[C.id];(!d||C.updatedAt&&C.updatedAt>d.updatedAt)&&(e.pages[c]=de({page:m,route:C,state:t,routeId:c,routePathInfo:p?.[c]}),f.logger.info("replace page by update time",c))}}else e.pageIds.push(c),e.pages[c]=de({page:m,route:C,state:t,routeId:c,routePathInfo:p?.[c]}),f.logger.info("add page",c)}if(n&&!s)for(const c of e.pageIds)b?.includes(c)||(delete e.pages[c],f.logger.info("delete page",c)),e.pageIds=[...e.pageIds].filter(h=>b?.includes(h))}else{for(const b of l){const p=r[b];if(p)if(e.pageIds.includes(p.id)){if(a==="replace")e.pages[p.id]=p;else if(a==="byUpdateTime"){const c=e.pages[p.id];(!c||p.updatedAt&&p.updatedAt>c.updatedAt)&&(e.pages[p.id]=p)}}else e.pageIds.push(p.id),e.pages[p.id]=p}for(const b of u){const p=S[b];if(p)if(e.routeIds.includes(p.id)){if(a==="replace")e.routes[p.id]=p;else if(a==="byUpdateTime"){const c=e.routes[p.id];(!c||p.updatedAt&&p.updatedAt>c.updatedAt)&&(e.routes[p.id]=p)}}else e.routeIds.push(p.id),e.routes[p.id]=p}}if(e.supportedLocales.splice(0,e.supportedLocales.length),e.supportedLocales.push(...we.default(P)),n)for(const b of Object.keys(e.components))delete e.components[b];let R=JSON.parse(JSON.stringify(t.components));R=Object.fromEntries(await Promise.all(Object.entries(R).map(async([b,p])=>{const c=await Ge(p?.data);return[b,{...p,data:c}]}))),Object.assign(e.components,R),Object.assign(e.config,JSON.parse(JSON.stringify(t.config))),Ae.default(t.resources.components)||(e.resources.components=JSON.parse(JSON.stringify(t.resources.components||{})))}const Ge=f.memoizeWithFs(async t=>{if(!Ae.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 f.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){f.logger.error("getPropertiesFromCode error",{componentId:t.id,name:t.name},{error:a})}}return t},{subdir:"getPropertiesFromCode"});let ae,J,oe,re;const Ve=()=>Ee.getResources({types:[{did:je,type:me},{did:Pt,type:me}]}),Vt=()=>{const t=Ve(),e={};return t.forEach(s=>{const a=Z.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 r of o)e[r]=g.join(n,r)}}),e};function ze(){return ae=(async()=>{const t=Ve();J=(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),oe=J.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=J.reduce((s,a)=>Object.assign(s,Object.fromEntries(Object.values(a.state.components).map(n=>[n.data.id,{blockletId:a.blockletId,component:n.data}]))),{});re=Object.fromEntries(await Promise.all(Object.entries(e).map(async([s,a])=>{const n=await Ge(a.component);return[s,{...a,component:n}]})))})(),ae}function Ye(t){const e=Me.default(async()=>{await ze().catch(s=>{f.logger.error("load resource states error",{error:s})}),await t?.({states:J,pages:oe,components:re})},3e3,{leading:!1,trailing:!0});return e(),w.default.events.on(w.default.Events.componentAdded,e),w.default.events.on(w.default.Events.componentRemoved,e),w.default.events.on(w.default.Events.componentStarted,e),w.default.events.on(w.default.Events.componentStopped,e),w.default.events.on(w.default.Events.componentUpdated,e),w.default.events.on(he,e),()=>{w.default.events.off(w.default.Events.componentAdded,e),w.default.events.off(w.default.Events.componentRemoved,e),w.default.events.off(w.default.Events.componentStarted,e),w.default.events.off(w.default.Events.componentStopped,e),w.default.events.off(w.default.Events.componentUpdated,e),w.default.events.off(he,e)}}const He=Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"),Ke=Symbol.for("GLOBAL_ENV_UPDATE_LISTENER_KEY"),ie=globalThis;ie[He]?.();ie[He]=Ye(async({pages:t,components:e})=>{const s=await O.getProjectIds();f.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=>{Je({projectId:a,pages:t,components:e})}))]).catch(a=>{f.logger.error("update resource states failed:",a)})});ie[Ke]?.();ie[Ke]=()=>{const t=()=>{O.pageUrlMapCache.clear(),f.logger.info("[Cache CLEAR ALL] clear all page url map cache by env update")};return w.default.events.on(w.default.Events.envUpdate,t),()=>{w.default.events.off(w.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 Je({projectId:t,pages:e,components:s}){const a=O.sharedInstances[t];if(!a){f.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 r=(await Oe.findAll({where:{projectId:t}})).map(u=>u.componentId),l=Object.fromEntries(Object.entries(s||{}).filter(([u])=>r.includes(u)));a.syncedStore.resources.components=l}f.logger.info(`update [${t}] resource states:`,{pages:Object.keys(a.syncedStore.resources.pages||{}).length,components:Object.keys(a.syncedStore.resources.components||{}).length})}async function We(t){return Je({projectId:t,pages:oe,components:re})}async function zt(){f.logger.info("trigger reload all project resource"),w.default.events.emit(he)}async function Yt({ensureLoaded:t=!0}={}){return t&&(ae??=ze(),await ae),{states:J,pages:oe,components:re}}exports.COMPONENT_DID=je;exports.PUBLISH_MODES=Bt;exports.Project=L;exports.RESOURCE_TYPE=me;exports.SITE_STATE_PATH=x;exports.STATE_MODES=xt;exports.SiteState=O;exports.downloadAsset=Fe;exports.downloadAssets=qe;exports.fromPackage=Ce;exports.getDefaultState=Ne;exports.getResourceStates=Yt;exports.initPackResourceStates=Ye;exports.mergeState=Ie;exports.toPackage=Be;exports.triggerReloadAllProjectResource=zt;exports.updateResourceStatesByProjectId=We;
|